Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Re: Unexpected truncation behavior (http://www.velocityreviews.com/forums/t962241-re-unexpected-truncation-behavior.html)

 glen herrmannsfeldt 06-28-2013 10:00 AM

Re: Unexpected truncation behavior

Giuseppe <giuseppe@somewhere.sw> wrote:

> I tried to understand why I can't get the message:

> "r1 is 10, r2 is 10"

> as result from the code below when I compile it with
> gcc4.8.1 *on Windows*. What I get is:

> "r1 is 10, r2 is 9"

> instead. Any other compiler and gcc on Linux display the
> expected message. Wouldn't the C language "require" the
> result to be the one I expect?

C is slightly more restrictive than Fortran on what is allowed
with floating point, but no.

Assuming your system uses binary floating point (which except
for some IBM systems is pretty much guaranteed) then the rounding
for decimal values that aren't exact binary fractions can easily
round down to 9.

There are so many articles around on the inexactness of binary
floating point representations of decimal fractions, you should

> #include <stdio.h>
> int main(void)
> {
> float a = 3.3f, b = 3.3f, c = 3.4f;
> double d = 3.3, e = 3.3, f = 3.4;
> int r1, r2;
> r1 = a + b + c;
> r2 = d + e + f;
> printf("r1 is %d, r2 is %d\n", r1, r2);
> return 0;
> }

-- glen

 BartC 06-28-2013 10:49 AM

Re: Unexpected truncation behavior

"Giuseppe" <giuseppe@somewhere.sw> wrote in message
news:-OidncNGfv8h_VDMnZ2dnUVZ8lOdnZ2d@giganews.com...
> Il 28/06/2013 12:00, glen herrmannsfeldt ha scritto:

>> Assuming your system uses binary floating point (which except
>> for some IBM systems is pretty much guaranteed) then the rounding
>> for decimal values that aren't exact binary fractions can easily
>> round down to 9.

> Thanks, I understand that, but it happens that when I print "d+e+f"
> with "printf("d + e + f is %f\n", d + e + f);" it displays 10.000000
> as expected. What I don't understand is why "r2 = d + e + f;" does not
> truncate that number to 10 and gives me 9 instead. This is what I mean:

You can't tell what's going to happen with floating point. If the actual
result is 9.999999999999999xxx, then it's possible that %f to the default
number of decimals will round up to 10.0, while conversion to int will
always round down.

You should use a rounding function when converting to int if that is what
you want. I can't remember what it is off-hand, but just adding 0.5 to a
floating point result before assigning to an int might do the trick for
positive values (however you will need the proper function).

--
Bartc

 Kenny McCormack 06-28-2013 11:11 AM

Re: Unexpected truncation behavior

In article <3cGdnUCqL_dM8FDMnZ2dnUVZ8sWdnZ2d@giganews.com>,
Giuseppe <giuseppe@somewhere.sw> wrote:
>Il 28/06/2013 12:54, Giuseppe ha scritto:
>
>> Thanks David Brown and BartC, this makes even more sense to me.
>> I was not aware of a possible difference in rounding with %f and
>> truncation in assignments to integer types.
>>

>
>I still have some doubts about why this behavior is only related
>to gcc on windows. The same compiler on Linux doesn't show the same
>behavior, nor do other compilers on both Windows and Linux.
>I'm not saying that operations between floating point numbers should
>lead to exact results, what I'm surprised of is the inconsistent
>behaviors for the same compiler on the same architecture on two different
>operating systems.

The stock clc answer is: It doesn't matter what happens. Anything can
happen. It is just as likely to depend on the phase of the moon as it is
to depend on the OS or the compiler in use.

As far as I can tell, C is perfectly free to report the result of:

2.1 + 3.4

as

9.76

--

Some of the more common characteristics of Asperger syndrome include:

* Inability to think in abstract ways (eg: puns, jokes, sarcasm, etc)
* Difficulties in empathising with others
* Problems with understanding another person's point of view
* Hampered conversational ability
* Problems with controlling feelings such as anger, depression
and anxiety
* Adherence to routines and schedules, and stress if expected routine
is disrupted
* Inability to manage appropriate social conduct
* Delayed understanding of sexual codes of conduct
* A narrow field of interests. For example a person with Asperger
syndrome may focus on learning all there is to know about
baseball statistics, politics or television shows.
* Anger and aggression when things do not happen as they want
* Sensitivity to criticism
* Eccentricity
* Behaviour varies from mildly unusual to quite aggressive
and difficult

 BartC 06-28-2013 11:30 AM

Re: Unexpected truncation behavior

"Giuseppe" <giuseppe@somewhere.sw> wrote in message
news:-oedndp7uZWG7VDMnZ2dnUVZ8gmdnZ2d@giganews.com...
> Il 28/06/2013 13:11, Kenny McCormack ha scritto:
>
>>
>> The stock clc answer is: It doesn't matter what happens. Anything can
>> happen. It is just as likely to depend on the phase of the moon as it is
>> to depend on the OS or the compiler in use.
>>
>> As far as I can tell, C is perfectly free to report the result of:
>>
>> 2.1 + 3.4
>>
>> as
>>
>> 9.76
>>

>
> So you are saying that we cannot do calculations with the C language?

I don't think he was being serious.

Adding 2.1 to 3.4 will give a result of approximately 5.5, but it might be
anything from 5.49999999999xxxx to 5.50000000000xxxx. It's this that you
need to bear in mind. Also that printf() can round values so it will appear
as though the result is 5.50000000 exactly.

--
Bartc

 Kenny McCormack 06-28-2013 11:39 AM

Re: Unexpected truncation behavior

In article <vtezt.3355\$yi1.1017@fx20.am4>, BartC <bc@freeuk.com> wrote:
....
>I don't think he was being serious.

Well, semi-serious.

I was making the point that if some inaccuracy is allowed, then how do we
know how much is allowed? I mean, 9.76 is actually pretty close to the right
answer. It's off by less than 5, which is a pretty small epsilon in the
grand scheme of things.

>Adding 2.1 to 3.4 will give a result of approximately 5.5, but it might be
>anything from 5.49999999999xxxx to 5.50000000000xxxx. It's this that you
>need to bear in mind. Also that printf() can round values so it will appear
>as though the result is 5.50000000 exactly.

Really? Really between 5.49999999999xxxx and 5.50000000000xxxx?

--
Is God willing to prevent evil, but not able? Then he is not omnipotent.
Is he able, but not willing? Then he is malevolent.
Is he both able and willing? Then whence cometh evil?
Is he neither able nor willing? Then why call him God?
~ Epicurus

 Johannes Bauer 06-28-2013 12:58 PM

Re: Unexpected truncation behavior

On 28.06.2013 13:30, BartC wrote:

>>> As far as I can tell, C is perfectly free to report the result of:
>>>
>>> 2.1 + 3.4
>>>
>>> as
>>>
>>> 9.76

>>
>> So you are saying that we cannot do calculations with the C language?

>
> I don't think he was being serious.

Actually he makes a very good point. If the standard answer is "well
that's just some floating-point artifact", then the question arises: How
bad may a floating-point implementation behave while still conforming to
the standard? Would his FP implementation that results 2.1 + 3.4 = 9.76
be standard compliant or not?

Regards,
Johannes

--
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?

> Zumindest nicht öffentlich!

Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <hidbv3\$om2\$1@speranza.aioe.org>

 Ken Brody 06-28-2013 01:52 PM

Re: Unexpected truncation behavior

On 6/28/2013 7:39 AM, Kenny McCormack wrote:
> In article <vtezt.3355\$yi1.1017@fx20.am4>, BartC <bc@freeuk.com> wrote:
> ...
>> I don't think he was being serious.

>
> Well, semi-serious.
>
> I was making the point that if some inaccuracy is allowed, then how do we
> know how much is allowed? I mean, 9.76 is actually pretty close to the right
> answer. It's off by less than 5, which is a pretty small epsilon in the
> grand scheme of things.
>
>> Adding 2.1 to 3.4 will give a result of approximately 5.5, but it might be
>> anything from 5.49999999999xxxx to 5.50000000000xxxx. It's this that you
>> need to bear in mind. Also that printf() can round values so it will appear
>> as though the result is 5.50000000 exactly.

>
> Really? Really between 5.49999999999xxxx and 5.50000000000xxxx?
>

He said "might be", not "is", or even "is probably".

 Ken Brody 06-28-2013 01:54 PM

Re: Unexpected truncation behavior

On 6/28/2013 7:42 AM, Giuseppe wrote:
> Il 28/06/2013 13:30, BartC ha scritto:

[...]
>> Adding 2.1 to 3.4 will give a result of approximately 5.5, but it might
>> be anything from 5.49999999999xxxx to 5.50000000000xxxx. It's this that
>> you need to bear in mind. Also that printf() can round values so it will
>> appear as though the result is 5.50000000 exactly.
>>

> Thanks, now it's clear. I tried with 3 compilers on both
> operating systems, I was probably surprised to see how the
> same compiler can behave differently. Thanks again.

If you change all of the "%f" specifiers in your printf's with "%.20f", you
may see a very subtle difference in the representation of the numbers.

 Kenny McCormack 06-28-2013 02:03 PM

Re: Unexpected truncation behavior

In article <44y59uz65n.fsf@be-well.ilk.org>,
Lowell Gilbert <lgusenet@be-well.ilk.org> wrote:
....
>"IEEE floating point") as well as the C standard, so although such
>a bogus implementation could exist, it doesn't.

That's not a CLC-compliant posting.

Besides, I wrote one (a standards compliant implementation) just last
night. And it generates 9.76 as the answer.

--
Those on the right constantly remind us that America is not a
democracy; now they claim that Obama is a threat to democracy.

 Tim Prince 06-28-2013 02:16 PM

Re: Unexpected truncation behavior

On 6/28/2013 10:08 AM, Giuseppe wrote:
> Il 28/06/2013 15:54, Ken Brody ha scritto:
>> On 6/28/2013 7:42 AM, Giuseppe wrote:
>>> Il 28/06/2013 13:30, BartC ha scritto:

>> [...]
>>>> Adding 2.1 to 3.4 will give a result of approximately 5.5, but it might
>>>> be anything from 5.49999999999xxxx to 5.50000000000xxxx. It's this that
>>>> you need to bear in mind. Also that printf() can round values so it
>>>> will
>>>> appear as though the result is 5.50000000 exactly.
>>>>
>>> Thanks, now it's clear. I tried with 3 compilers on both
>>> operating systems, I was probably surprised to see how the
>>> same compiler can behave differently. Thanks again.

>>
>> If you change all of the "%f" specifiers in your printf's with "%.20f",
>> you may see a very subtle difference in the representation of the
>> numbers.

>
> Yes, I'm aware of this, thanks anyway. What confused me was that
> in this code:
>
> #include <stdio.h>
> int main(void)
> {
> float a = 3.3f, b = 3.3f, c = 3.4f;
> double d = 3.3, e = 3.3, f = 3.4;
> int r1, r2;
> r1 = a + b + c;
> r2 = d + e + f;
> printf("d = %f e = %f f = %f\n", d, e, f);
> printf("d + e + f is %f\n", d + e + f);
> printf("r1 is %d, r2 is %d\n", r1, r2);
> return 0;
> }
>
> no matter how "d + e + f" is approximated, when it is assigned to r2 it's
> not truncated the same way by the same compiler (gcc 4.8.1) on windows
> and linux. In the former case r2 is 9 and the latter r2 is 10.
>

Presumably, you used different -march options (or defaults for those).
Default for gcc 32-bit (i486) remains to use 387. If you showed the
screen echos with -v, you've strung out this threads so far I couldn't
find them.

--
Tim Prince

All times are GMT. The time now is 09:52 PM.