Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: Unexpected truncation behavior

Reply
Thread Tools

Re: Unexpected truncation behavior

 
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      06-28-2013
Giuseppe <(E-Mail Removed)> 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
find one and read it.

> #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
 
Reply With Quote
 
 
 
 
BartC
Guest
Posts: n/a
 
      06-28-2013
"Giuseppe" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> 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
 
Reply With Quote
 
 
 
 
Kenny McCormack
Guest
Posts: n/a
 
      06-28-2013
In article <(E-Mail Removed)>,
Giuseppe <(E-Mail Removed)> 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

 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      06-28-2013


"Giuseppe" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
> 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

 
Reply With Quote
 
Kenny McCormack
Guest
Posts: n/a
 
      06-28-2013
In article <vtezt.3355$(E-Mail Removed)4>, BartC <(E-Mail Removed)> 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?

C & V, please?

--
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

 
Reply With Quote
 
Johannes Bauer
Guest
Posts: n/a
 
      06-28-2013
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$(E-Mail Removed)>
 
Reply With Quote
 
Ken Brody
Guest
Posts: n/a
 
      06-28-2013
On 6/28/2013 7:39 AM, Kenny McCormack wrote:
> In article <vtezt.3355$(E-Mail Removed)4>, BartC <(E-Mail Removed)> 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?
>
> C & V, please?


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

 
Reply With Quote
 
Ken Brody
Guest
Posts: n/a
 
      06-28-2013
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.
 
Reply With Quote
 
Kenny McCormack
Guest
Posts: n/a
 
      06-28-2013
In article <(E-Mail Removed)>,
Lowell Gilbert <(E-Mail Removed)> 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.
 
Reply With Quote
 
Tim Prince
Guest
Posts: n/a
 
      06-28-2013
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Unexpected truncation behavior mark.bluemel@gmail.com C Programming 3 06-29-2013 12:03 AM
setString 32 character limit? - String data right truncation jameswhiteley@hbosplc.com Java 3 10-11-2006 02:41 PM
MySql Data Truncation Marcelo Java 3 12-21-2005 01:29 AM
Text Truncation manas ASP .Net 1 07-01-2005 10:41 PM
Truncation of long filename plxjb Computer Information 0 09-28-2004 06:40 AM



Advertisments