Hi all!
The following piece of code has (for me) completely unexpected behaviour.
(I compile it with gcc-Version 4.0.3)
Something goes wrong with the integer to float conversion.
Maybe somebody out there understands what happens.
Essentially, when I subtract the (double) function value GRID_POINT(2) from
a variable which has been assigned the same value before this gives a
non-zero result and I really do not understand why.
The program prints
5.0000000000000 00000e-01; -2.7755575615628 91351e-17;
0.0000000000000 00000e+00
And the comparison
if(temp1==GRID_ POINT(2))
has negative outcome.
When I replace
((double)(i)) by 2.0
everything behaves as expected. So the output is
5.0000000000000 00000e-01; 0.0000000000000 00000e+00; 0.0000000000000 00000e+00
But: even if the integer to float conversion is inexact (which, I think,
should not be the case) something like
temp1 = GRID_POINT(2);
temp3 = temp1-GRID_POINT(2);
should still result in temp3==0.0, whatever function GRID_POINT does.
What do You think?
Thank you!
---------------------------------------------------
#include <stdio.h>
double GRID_POINT(int i);
double GRID_POINT(int i)
{
return ( 0.1 + ( (80.1-0.1)/(400.0) )*((double)(i)) );
}
int main (void) {
double temp1, temp2, temp3;
temp1 = GRID_POINT(2);
temp2 = GRID_POINT(2);
temp3 = temp1-GRID_POINT(2);
printf("%.18e; %.18e; %.18e\n", temp1, temp3, temp1-temp2 );
if(temp1==GRID_ POINT(2)){
printf("these two are equal\n");
}
return 0;
}
---------------------------------------------------
Dec 12 '07
39 3572
Chris Torek wrote:
In article <fj**********@a ioe.org>
Mark Bluemel <ma**********@p obox.comwrote:
>... read http://www.network-theory.co.uk/docs...cintro_70.html
It answers your questions fairly comprehensively and gives a simple way of disabling extended precision for the duration of a program's execution.
It also notes, in passing, that setting the precision field in
the FPU control word does *not* affect the exponent range. This
means that the in-FPU computations are *still* not quite what
one might expect from an IEEE implementation.
I have the same note (with an example) at the
end of <http://web.torek.net/torek/c/numbers.html>.
As someone else noted else-thread, one can get "proper" IEEE floating
point on the x86 using gcc's "-ffloat-store" flag. This does,
however, slow down computation.
And still doesn't work for the OP's testcase :-
$ cat gr.c
#include <stdio.h>
double GRID_POINT(int i) {
return ( 0.1 + ( (80.1-0.1)/(400.0) )*((double)(i)) );
}
int main (void) {
double temp1 = GRID_POINT(2);
double temp2 = temp1-GRID_POINT(2);
printf("%.18e; %.18e\n", temp1, temp2);
return 0;
}
$ cc -ffloat-store gr.c -o gr
$ ./gr
5.0000000000000 00000e-01; -2.7755575615628 91351e-17
As I commented else-thread -ffloat-store doesn't appear to alter how
a floating point return value from a function (presumably in a register)
is handled. This is probably covered by the comment in the manual page
:-
... "a few programs rely on the precise definition of IEEE floating
point. Use -ffloat-store for such programs, _after modifying them to
store all pertinent intermediate computations into variables_."
Mark Bluemel <ma**********@p obox.comwrites:
Chris Torek wrote:
<snip>
>As someone else noted else-thread, one can get "proper" IEEE floating point on the x86 using gcc's "-ffloat-store" flag. This does, however, slow down computation.
And still doesn't work for the OP's testcase :-
$ cat gr.c
#include <stdio.h>
double GRID_POINT(int i) {
return ( 0.1 + ( (80.1-0.1)/(400.0) )*((double)(i)) );
}
int main (void) {
double temp1 = GRID_POINT(2);
double temp2 = temp1-GRID_POINT(2);
printf("%.18e; %.18e\n", temp1, temp2);
return 0;
}
$ cc -ffloat-store gr.c -o gr
$ ./gr
5.0000000000000 00000e-01; -2.7755575615628 91351e-17
A data point. It does here:
$ gcc -ffloat-store gr.c -o gr
$ ./gr
5.0000000000000 00000e-01; 0.0000000000000 00000e+00
$ gcc gr.c -o gr
$ ./gr
5.0000000000000 00000e-01; -2.7755575615628 91351e-17
$ gcc --version
gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
<snip>
--
Ben.
On Thu, 13 Dec 2007 18:59:35 +0000, Mark Bluemel wrote:
Chris Torek wrote:
>> As someone else noted else-thread, one can get "proper" IEEE floating point on the x86 using gcc's "-ffloat-store" flag. This does, however, slow down computation.
And still doesn't work for the OP's testcase :-
$ cat gr.c
#include <stdio.h>
double GRID_POINT(int i) {
return ( 0.1 + ( (80.1-0.1)/(400.0) )*((double)(i)) );
}
int main (void) {
double temp1 = GRID_POINT(2);
double temp2 = temp1-GRID_POINT(2);
printf("%.18e; %.18e\n", temp1, temp2);
return 0;
}
$ cc -ffloat-store gr.c -o gr
$ ./gr
5.0000000000000 00000e-01; -2.7755575615628 91351e-17
This is OT, but the above happens because GRID_POINT(2) in the second call
is an 'unnamed temporary', and is not necessarily flushed to the memory by
gcc (even with -ffloat-store).
See http://arxiv.org/abs/cs/0701192 - "The pitfalls of verifying
floating-point computations".
-Alok
>Chris Torek wrote:
>As someone else noted else-thread, one can get "proper" IEEE floating point on the x86 using gcc's "-ffloat-store" flag. This does, however, slow down computation.
In article <fj**********@a ioe.org>
Mark Bluemel <ma**********@p obox.comwrote:
>And still doesn't work for the OP's testcase ... [snip code; but it
reappears below, modified slightly]
>As I commented else-thread -ffloat-store doesn't appear to alter how a floating point return value from a function (presumably in a register) is handled.
This is allowed by the Standard -- you have to store the result
in a temporary variable, or use a cast, to trim off "extra"
precision.
>This is probably covered by the comment in the manual page :-
... "a few programs rely on the precise definition of IEEE floating
point. Use -ffloat-store for such programs, _after modifying them to
store all pertinent intermediate computations into variables_."
If gcc fails to store the number through memory (on the x86, that
is; this is how -ffloat-store trims the excess precision and
exponents) on a cast, that would be a bug.
On my Linux box here, the bug is not showing up, with the same
compilation options you used, or indeed any others. Then again,
I probably have a different Linux, different version of gcc, and
different libraries. (In particular I think this Linux and/or
libc defaults C programs to double, not extended, precision in
the FPU control word.)
Here is the modified test-case; compile with -DCAST_AWAY_EXCE SS to
test the effect of adding a cast.
% cat gr.c
#include <stdio.h>
double GRID_POINT(int i) {
return ( 0.1 + ( (80.1-0.1)/(400.0) )*((double)(i)) );
}
#ifdef USE_CAST
#define CAST_AWAY_EXCES S (double)
#else
#define CAST_AWAY_EXCES S /* nothing */
#endif
int main(void) {
double temp1 = GRID_POINT(2);
double temp2 = temp1 - CAST_AWAY_EXCES S GRID_POINT(2);
printf("%.18e; %.18e\n", temp1, temp2);
return 0;
}
% cc -o gr -ffloat-store gr.c
% ./gr
5.0000000000000 00000e-01; 0.0000000000000 00000e+00
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Ben Bacarisse wrote:
Mark Bluemel <ma**********@p obox.comwrites:
>Chris Torek wrote:
<snip>
>>As someone else noted else-thread, one can get "proper" IEEE floating point on the x86 using gcc's "-ffloat-store" flag. This does, however, slow down computation.
And still doesn't work for the OP's testcase :-
[Snip]
>
A data point. It does here:
$ gcc -ffloat-store gr.c -o gr
$ ./gr
5.0000000000000 00000e-01; 0.0000000000000 00000e+00
$ gcc gr.c -o gr
$ ./gr
5.0000000000000 00000e-01; -2.7755575615628 91351e-17
$ gcc --version
gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
Looks like I need a later gcc then :-)
James Kuyper wrote:
ym******@gmail. com wrote:
.... snip ...
>
>You quoted it: "How could the standard guarantee ANYTHING about the precision of floating point calculations... "
Well, actually, the numerical limits section does specify the
precision. However, getting an inaccurate value with high
precision is not something most numerical analysts would be
happy about.
Please describe how you implement infinite precision in a finite
number of bits.
--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home .att.net>
--
Posted via a free Usenet account from http://www.teranews.com
CBFalconer wrote, On 13/12/07 15:05:
James Kuyper wrote:
>ym******@gmail. com wrote:
... snip ...
>>You quoted it: "How could the standard guarantee ANYTHING about the precision of floating point calculations... "
Well, actually, the numerical limits section does specify the precision. However, getting an inaccurate value with high precision is not something most numerical analysts would be happy about.
Please describe how you implement infinite precision in a finite
number of bits.
That has nothing to do with James's comment. You do not need infinite
precision to get guaranteed accuracy. You do not need infinite precision
to get high precision.
--
Flash Gordon
CBFalconer wrote:
James Kuyper wrote:
ym******@gmail. com wrote:
... snip ...
You quoted it: "How could the standard guarantee ANYTHING about
the precision of floating point calculations... "
Well, actually, the numerical limits section does specify the
precision. However, getting an inaccurate value with high
precision is not something most numerical analysts would be
happy about.
Please describe how you implement infinite precision in a finite
number of bits.
Do you have any particular reason for posing such an absurd challenge?
It's not relevant to any point that I, or anyone else, has made so far
in this discussion. Maybe if you explain more what you're looking for,
I might be able to help.
CBFalconer <cb********@yah oo.comwrites:
James Kuyper wrote:
>ym******@gmail. com wrote:
... snip ...
>>
>>You quoted it: "How could the standard guarantee ANYTHING about the precision of floating point calculations... "
Well, actually, the numerical limits section does specify the precision. However, getting an inaccurate value with high precision is not something most numerical analysts would be happy about.
Please describe how you implement infinite precision in a finite
number of bits.
I think you misunderstood James's use of the phrase "inaccurate
value".
For example, given a precision of 5 digits after the decimal point,
3.14159 is an accurate value of pi (to within the stated precision);
3.12345 is an innaccurate value of pi. Infinite precision is not
required for what's being discussed.
--
Keith Thompson (The_Other_Keit h) <ks***@mib.or g>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
On Wed, 12 Dec 2007 16:09:12 +0100, rembremading
<re**********@g mx.netwrote:
>Hi all!
The following piece of code has (for me) completely unexpected behaviour. (I compile it with gcc-Version 4.0.3) Something goes wrong with the integer to float conversion. Maybe somebody out there understands what happens. Essentially, when I subtract the (double) function value GRID_POINT(2) from a variable which has been assigned the same value before this gives a non-zero result and I really do not understand why.
The program prints 5.000000000000 000000e-01; -2.7755575615628 91351e-17; 0.000000000000 000000e+00
And the comparison if(temp1==GRID _POINT(2)) has negative outcome.
When I replace ((double)(i) ) by 2.0 everything behaves as expected. So the output is 5.000000000000 000000e-01; 0.0000000000000 00000e+00; 0.0000000000000 00000e+00
But: even if the integer to float conversion is inexact (which, I think, should not be the case) something like temp1 = GRID_POINT(2); temp3 = temp1-GRID_POINT(2); should still result in temp3==0.0, whatever function GRID_POINT does.
What do You think?
I think you should output the internal representation of the doubles
in hex so you can see the actual results of your computation, not what
printf thinks it should display.
> Thank you!
--------------------------------------------------- #include <stdio.h>
double GRID_POINT(int i);
double GRID_POINT(int i) {
return ( 0.1 + ( (80.1-0.1)/(400.0) )*((double)(i)) );
What purpose do you think the cast serves?
All the parentheses are superfluous except the pair around the
subtraction.
Do you really think 80.1 - .1 is exactly equal to 80.0?
Even if it is on your system, do you think 80.0/400.0 is exactly equal
to 0.2? Can any floating point value be exactly equal to 0.2 on your
system? (It is possible on mine but very few other people here have a
system with decimal floating point; most use binary.)
>}
int main (void) {
double temp1, temp2, temp3;
temp1 = GRID_POINT(2);
temp2 = GRID_POINT(2);
temp3 = temp1-GRID_POINT(2);
printf("%.18e; %.18e; %.18e\n", temp1, temp3, temp1-temp2 );
if(temp1==GRID_ POINT(2)){
printf("these two are equal\n");
}
return 0; } ---------------------------------------------------
Remove del for email This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: rz0 |
last post by:
Hi all,
This is a question about both C89 and C99 and is based on my partial
reading of the standard drafts (one from before C89 but mainly
N1124). If appropriate, please give a separate answer for each version
of the language.
Let's consider the conversion from a given floating real type to a
specific integer type.
|
by: Nonoize |
last post by:
Hi all,
Really dumb question but I don't know how to resolve it. Looked in help and
evry book I have.
I have a table where the primary key was set as an Integer and its reached
over 140K worth of records and the numbering has restarted from 1.
I realize now that I should have set it to double. Can someone please advise
how I can save my existing records and restart the numbering from say
|
by: Mike S |
last post by:
Does anyone know the logic behind why in VB.NET the result of a
floating-point division ('/') is -rounded- on being converted to an
integer type, such as with statements like
Dim x As Integer = 2/3 'after assignment, x is 1, whereas a sane person
would say it should be 0
Does Microsoft have a reason for this design decision? I understand
that this type of rounding can reduce the overall error in long
computation chains by reducing the...
|
by: Candace |
last post by:
I am using the following code to pick off each digit of a number, from right
to left. The number I am working with is 84357. So for the first iteration it
should return the number 7 and for the second iteration it should return the
number 5, and so on. But for some reason on the first iteration returns the
expected results. Each subsequent iteration returns the number plus 1. In
order words, when I run the program I am getting: 7, 6, 4, and...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
| |
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
| |
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |