0

This is Solution To Problem Hangover on POJ and i think the Logic is Correct but My Solution is not Working on POJ Compiler but it's Working Correct on My g++ Compiler.What's Wrong with My Solution. Here is the Problem Link. http://poj.org/problem?id=1003

I Tried To think what is Wrong and i think there is something Wrong how poj take input output and how i am providing.

#include<iostream>
#include<cstdlib>
using namespace std;

int main()
{
    float desired=1.00;
    while(1)
    {
        cin>>desired;
        if(desired!=0 and desired<=5.20 and desired>=0.01)
        {
            float sum=0;
            int denominator=2;
            float num=1;
            int total=0;
            while(sum<=desired)
            {
                num=1.00/denominator;
                sum+=num;
                total+=1;
                ++denominator;
            }
            cout<<total<<"\n";
        }
        else
            exit(0);
        }
    return 0;
}

I expect my Solution is True but i can't think where i am wrong. I expect Output 1 card(s) 1card(s) from input 0.04 0.01 0.01 since it will terminate on 0.00 it should give two output but it's giving only one output. Here is the link of output on IDEONE http://ideone.com/1o6HAz

rootOcean
  • 13
  • 2
  • `desired>=0.01` - may not trigger on string `0.01` converted to float, you can get `0.00999999` – firda Oct 01 '19 at 08:43
  • 1
    Use `double` rather than `float`. – n. m. could be an AI Oct 01 '19 at 08:52
  • @frida there are no strings in `desired>=0.01`. – n. m. could be an AI Oct 01 '19 at 09:04
  • @n.m.: `cin>>desired`, that is string parsing. Change `desired>=0.01` to `desired>=0.009` and IdeOne is happy :) – firda Oct 01 '19 at 12:52
  • P.S.: And yes, 0.01 is double, while desired is float... still problem of inexact floating-point representation and comparision. – firda Oct 01 '19 at 12:56
  • @frida desired is parsed from a string, but the 0.01 literal is parsed from a string (by the compiler) too in exactly the same way. Except it's double and desired is float. Which is the real reason for the error, and not the mythical string parsing. You would get the same exact error by saying `float desired = 0.01;` – n. m. could be an AI Oct 01 '19 at 15:48
  • Even I change Float to Double and change desired>=0.09 My solution is Wrong.I don't Know what is wrong with my Solution With the Given Problem? Problem Link:-http://poj.org/problem?id=1003 – rootOcean Oct 01 '19 at 16:09
  • If you have a different question, please ask a different question. You should post a [mcve], this includes the program, the input, the desired output, and the actual output. – n. m. could be an AI Oct 01 '19 at 19:44
  • @n.m: "parsed from a string (by the compiler) too in exactly the same way" - that is simply not true (not guaranteed to be true). Not even using `double` or comparing `desired >= 0.01f` (both floats) is guaranteed to work (different fp-modes: precise, strict, fast etc.). What looks like "0.01" may not be, not exactly and that is the point. Another possible problem of the code is `sum+=num` for similar reason: **loss of precision**, the `num` may become too small compared to `sum`, which may result in `sum` stop changing after some number of iterations. – firda Oct 02 '19 at 07:44
  • @firda I have successfully submitted the solution the problem was that I used float first which should be double for precision and there was no need of that exit statement simply while(desired) will do the work if the desired will be 0.0 then the while will be wrong and we will get out of the program. Thanks. – rootOcean Oct 02 '19 at 07:51
  • @frida As far as I understand it, in any IEEE754 compliant implementation what is written as 0.01 is guaranteed to be precisely 0011111110000100011110101110000101000111101011100001010001111011 in binary, no matter what. I suspect that the C standard alone also guarantees 0.01 written in program text to be exactly equal to 0.01 converted from a string (if both are of the same type of course), but I don't have time for a thorough check. Regardless of what the standard says, any implementation that doesn't provide that is simply buggy and would not survive for long. – n. m. could be an AI Oct 02 '19 at 08:06
  • @n.m.: First, I am FIRDA not FRIDA, not getting notifications when you cannot spell my nickname correctly. Second, there are options in many compilers exactly for this, /fp:strict should be the option for what you expect. BTW, I work with small devices, where you often have to trade speed and size for precision ;) – firda Oct 02 '19 at 08:12
  • @rootOcean: Good for you, `double` may be just enough for the constraints given, but I hope you learned today, that floating-point numbers do not have exact representation (we think in decimal, but computers work with binary, some numbers that look nice in decimal can be like 1/3 with never-ending expansion for the computer) and that can cause various problems (loosing precision, 0.01 becoming 0.0099 etc, adding big and small doing nothing). BTW, try searching for Harmonic numbers: https://en.wikipedia.org/wiki/Harmonic_number – firda Oct 02 '19 at 08:18
  • @firda sorry my mistake, on mobile I don't get @ popups so it's easy to mistype. /fp:strict and other fp options do not apply to conversions but to calculations in user programs. If you can show me any mainstream compiler under any fp option not converting 0.01 to what IEEE prescribes, either as a literal or converted from a string, I will eat my hat. – n. m. could be an AI Oct 02 '19 at 08:19
  • @n.m.: The compiler itself can be compiled with /fp:strict but `cin>>desired` is subject to the option and therefore may parse the input to something else (especially with /fp:fast). – firda Oct 02 '19 at 08:21
  • @firda How is `cin>>desired` subject to the option exactly? Can you show it *in practice*? It's just a function call to the standard library, which is I hope not compiled with anything like /fp.fast. – n. m. could be an AI Oct 02 '19 at 08:26
  • @firda I checked the C++ standard. It says "value is set to the parsed value, after rounding according to round_­to_­nearest". Full stop, end of story. – n. m. could be an AI Oct 02 '19 at 08:43
  • @n.m.: IAR (fp: relaxed): printf("%08llx\n%08llx", 1.0000000000000003, atof("1.0000000000000003")); => 3ff0000000000001 3ff0000000000002 – firda Oct 02 '19 at 09:04
  • @firda Undefined behaviour, and not reproducible here, getting 3ff0000000000001 in both cases with /fp.relaxed under VC 19.22.27905 – n. m. could be an AI Oct 02 '19 at 09:39
  • @firda I distantly remember some nasty MSC floating point bugs that made us switch to ICC some 15 years ago or so. At any rate if you are using fp.relaxed or anything like that, you should not be asking such questions! – n. m. could be an AI Oct 02 '19 at 09:49
  • @n.m.: I believe that the reason you cannot reproduce it is because you do not have CPU/MCU without FPU (co-processor). I do have one - ATSAMG55, ARM Cortex-M4. It is not a bug, it is a feature and it is quite normal to use relaxed fp on such architecture (12MHz, 64kB RAM). ... "If you can show me any mainstream compiler under any fp option not converting 0.01 to what IEEE prescribes, either as a literal or converted from a string, I will eat my hat" ... IAR is pretty main stream for ARM/embedded, but I had to use different number :) Anyway, we are done I think. – firda Oct 02 '19 at 10:13
  • @firda no, it is a bug/non-compliance. 3ff0000000000002 violates what the standard says. – n. m. could be an AI Oct 02 '19 at 10:32

0 Answers0