Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Are floating-point zeros required to stay exact?

Reply
Thread Tools

Are floating-point zeros required to stay exact?

 
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      02-28-2013
Eric Sosman <(E-Mail Removed)> wrote:
> On 2/27/2013 3:29 PM, James Kuyper wrote:
>> On 02/27/2013 02:56 PM, army1987 wrote:
>>> Is this guaranteed to always work in all conforming implementations?


>>> #include <stdio.h>
>>> #include <stdlib.h>
>>> int main(void)
>>> {
>>> double zero = 0.;
>>> if (zero == 0.) {
>>> puts("Okay!");
>>> return 0;
>>> } else {
>>> puts("Uh-oh!");
>>> return EXIT_FAILURE;
>>> }
>>> }


(snip)

>> No.
>> "The accuracy of the floating-point operations (+, -, *, /) and of the
>> library functions in <math.h> and <complex.h> that return floating-point
>> results is implementation defined, as is the accuracy of the conversion
>> between floating-point internal representations and string
>> representations performed by the library functions in <stdio.h>,
>> <stdlib.h>, and <wchar.h>. The implementation may state that the
>> accuracy is unknown." (5.2.4.2.2p6)


> I don't think this paragraph applies. None of (+, -, *, /)
> is performed, no library function from <math.h> or <complex.h> is
> used, and there are no conversions from strings to floating-point.


> Instead, I think we have to rely on 6.4.4.2p5:


> "Floating constants are converted to internal format as
> if at translation-time. [...] All floating constants of
> the same source form shall convert to the same internal
> format with the same value."


I believe that C is more strict on floating point values
than Fortran. As I understand it, a valid Fortran implementation
could give 46 as the value of all floating point operations,
though not so good in QoI.

As mentioned, some implementations have different routines
for compile time conversion and run-time (library routine)
conversions. That is especially true for cross compilers.
(And, even more, when the host and target have different
floating point representation.)

> Thus, both appearances of `0.' produce the same value, and the
> same value compares equal to itself. (In p7 we learn that the
> value "should" be the same that the library would produce for a
> conversion, but that's a "should" and not a "shall," and is in
> a subsection titled "Recommended practice." I think it would be
> hard to argue that p7's "should" brings 5.2.4.2.2p6 into play.)


Not likely, but I suppose someone might design a system with
no representation for zero, but instead only allow for the
smallest positive value. Though in that case I would hope that
the equality would still be true. It might be, though, that
the value with all bits zero isn't 0.0.

> I suppose that although both appearances of `0.' must produce
> the same value, that value might not be "zero." If instead of
> `if (zero == 0.)' the program had used `if (!zero)', perhaps it
> is possible that "Uh-oh!" could be printed. On a really perverse
> implementation, I imagine `0.' and `0.0' and `.0' and `0e0' and so
> on could produce different values; it might be a QOI issue.


>> In principle, that clause allows LDBL_MIN==LDBL_MAX to be true; only by
>> checking your implementation's documentation can you be sure that the
>> accuracy of your implementation is good enough for
>> LDBL_MIN==LDBL_MAX to be guaranteed false. [...]


> Could you explain your reasoning here? 5.2.4.2.2p{12,13}
> require that LDBL_{MAX,MIN} be representable long double values,
> hence, no round-off or approximation is involved. Also, `==' is
> not in the list of operators whose accuracy is unspecified (and
> indeed, floating-point `==' can be evaluated without any rounding
> at all).


A low QoI implementation could have only one value, and it might
not be zero. As far as I know, that is true in Fortran, but
maybe not in C.

-- glen

 
Reply With Quote
 
 
 
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      02-28-2013
Shao Miller <(E-Mail Removed)> wrote:
> On 2/27/2013 17:19, James Kuyper wrote:
>> On 02/27/2013 04:48 PM, Eric Sosman wrote:
>>> On 2/27/2013 3:29 PM, James Kuyper wrote:


>>>> "The accuracy of the floating-point operations (+, -, *, /) and of the
>>>> library functions in <math.h> and <complex.h> that return floating-point
>>>> results is implementation defined, as is the accuracy of the conversion
>>>> between floating-point internal representations and string
>>>> representations performed by the library functions in <stdio.h>,
>>>> <stdlib.h>, and <wchar.h>. The implementation may state that the
>>>> accuracy is unknown." (5.2.4.2.2p6)


(snip)
>> I've always assumed that "floating point operations" was the key phrase,
>> and that "(+, -, *, /)" should be taken only as examples, implying, in
>> particular, that the relational and equality operators were also
>> intended to be covered by that clause.


(snip)
> I seem to recall that 0 is special. It can be positive or negative,
> but it is zero. It's not "imprecise zero," it's zero. The result
> of a computation might or might not be zero, but there is no
> computation, here.


Yes, I believe that zero is special in that -0.0 has to compare the
same as +0.0, but that wasn't the question.

The biggest cause of floating point comparison problems is the
x87 keeping temporary values with extra precision. That shouldn't
cause problems with zero, but can easily cause problems when
subtracting values that are supposed to be equal, and then
comparing to zero.

Then there is the Cray machine with non-commutative multiplication.
I don't remember that zero was affected, but it might be that
the expression 0.0*x==0.0 could be false on that one.

> Consider 5.2.4.2.2p4's mention of "zero" alongside infinities and NaNs.
> These three are all special. Also consider the alternative...
> 6.5.9p3 says that it'll be either true or false for a given pair. This
> seems to suggest that the values matter, and the values are the same,
> and having them compare as unequal would be nonsense.


Well, pretty much you get no more than the machine gives you.
If you run on a machine with strange properties, then expect
strange results.

-- glen
 
Reply With Quote
 
 
 
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      02-28-2013
Robert Wessel <(E-Mail Removed)> wrote:

(snip)
> I'm not sure if we're discussing only IEEE-style FP or not, but there
> have been FP formats* where the mantissa was stored twos-complement.
> On such a machine negation could well overflow.


> *The CDC Cyber 205, for example. Whether or not there have been C
> implementations for such is a different question.


I believe many DSPs also used twos complement significand.

The PDP-10 twos complements the whole word.

-- glen
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      02-28-2013
On 02/27/2013 09:30 PM, Robert Wessel wrote:
....
> I'm not sure if we're discussing only IEEE-style FP or not, but there


I'm discussing the fact that the C standard allows arbitrarily low
accuracy for floating point operations. It even allows accuracy so low
that LDBL_EPSILON - LDBL_MAX == LDBL_MAX - LDBL_EPSILON. That's
definitively not IEEE compliant. IEEE requires the maximum feasible
accuracy (or very close to it) for every operation.
--
James Kuyper
 
Reply With Quote
 
Fred J. Tydeman
Guest
Posts: n/a
 
      02-28-2013
On Thu, 28 Feb 2013 00:50:49 UTC, Shao Miller <(E-Mail Removed)> wrote:

> Is there any floating point representation where precise zero cannot be
> represented? Strong evidence, indeed.


Systems that use a logarithmic number system:
http://en.wikipedia.org/wiki/Logarithmic_number_system
---
Fred J. Tydeman Tydeman Consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Testing, numerics, programming
+1 (775) 287-5904 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-28-2013
army1987 <(E-Mail Removed)> writes:

> Is this guaranteed to always work in all conforming implementations?
>
> #include <stdio.h>
> #include <stdlib.h>
> int main(void)
> {
> double zero = 0.;
> if (zero == 0.) {
> puts("Okay!");
> return 0;
> } else {
> puts("Uh-oh!");
> return EXIT_FAILURE;
> }
> }


The thread seems to have gone off on some tangent about operations that
are not involved here so I'll just stick these marks "out there" in case
they are useful.

The model that C uses for floating point means that all conforming
implementations must have at least one exact representation for zero.

For decimal floating constants like '0.', C does not guarantee that it
will be converted to this value! The conversion may produce either of
the two adjoining values, but the implementation must specify what
happens. If it says that the conversion is always done the same way,
the two constants will convert to the same value and the test will
evaluate to true, even if the value used is not exactly zero.

Form a QoI point of view, I can't conceive of an implementation that
does not convert '0.' to an exact representation of zero much less one
where the two '0.'s in the code above convert to different values.

Curiously, using 0 instead of '0.' is safer because the conversion
from an integer constant to a floating point value must be exact if the
value can be represented in the floating type.

If you know that you will be using a floating point system that has a
radix that is a power of two, you could also use a hexadecimal floating
point constant because that, too, will be "exactly rounded", but there
is no advantage over using an integer constant.

--
Ben.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-28-2013
"Fred J. Tydeman" <(E-Mail Removed)> writes:

> On Thu, 28 Feb 2013 00:50:49 UTC, Shao Miller <(E-Mail Removed)> wrote:
>
>> Is there any floating point representation where precise zero cannot be
>> represented? Strong evidence, indeed.

>
> Systems that use a logarithmic number system:
> http://en.wikipedia.org/wiki/Logarithmic_number_system


....but not permitted in C implementations. The C standard lays out a
model for how floating point types must be represented, and zero can
always be represented exactly.

--
Ben.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      02-28-2013
On 02/28/2013 10:06 AM, Ben Bacarisse wrote:
> "Fred J. Tydeman" <(E-Mail Removed)> writes:
>
>> On Thu, 28 Feb 2013 00:50:49 UTC, Shao Miller <(E-Mail Removed)> wrote:
>>
>>> Is there any floating point representation where precise zero cannot be
>>> represented? Strong evidence, indeed.

>>
>> Systems that use a logarithmic number system:
>> http://en.wikipedia.org/wiki/Logarithmic_number_system

>
> ...but not permitted in C implementations. The C standard lays out a
> model for how floating point types must be represented, and zero can
> always be represented exactly.
>


Footnote 21: "The floating-point model is intended to clarify the
description of each floating-point characteristic and does not require
the floating-point arithmetic of the implementation to be identical."
--
James Kuyper

 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      02-28-2013
James Kuyper <(E-Mail Removed)> wrote:
> On 02/28/2013 10:06 AM, Ben Bacarisse wrote:
>> "Fred J. Tydeman" <(E-Mail Removed)> writes:


>>> On Thu, 28 Feb 2013 00:50:49 UTC, Shao Miller <(E-Mail Removed)> wrote:


>>>> Is there any floating point representation where precise zero cannot be
>>>> represented? Strong evidence, indeed.


>>> Systems that use a logarithmic number system:
>>> http://en.wikipedia.org/wiki/Logarithmic_number_system


>> ...but not permitted in C implementations. The C standard lays out a
>> model for how floating point types must be represented, and zero can
>> always be represented exactly.


> Footnote 21: "The floating-point model is intended to clarify the
> description of each floating-point characteristic and does not require
> the floating-point arithmetic of the implementation to be identical."


In systems that don't use a hidden '1', there is a natural zero.
With a hidden '1', zero is a special case. If you leave out the
special case, the result is similar to logarithmic, though addition
is much easier. (Note the reason why floating point does not
have a 'mantissa'.)

-- glen
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      02-28-2013
Ben Bacarisse <(E-Mail Removed)> writes:

> "Fred J. Tydeman" <(E-Mail Removed)> writes:
>
>> On Thu, 28 Feb 2013 00:50:49 UTC, Shao Miller <(E-Mail Removed)> wrote:
>>
>>> Is there any floating point representation where precise zero cannot be
>>> represented? Strong evidence, indeed.

>>
>> Systems that use a logarithmic number system:
>> http://en.wikipedia.org/wiki/Logarithmic_number_system

>
> ...but not permitted in C implementations. The C standard lays out a
> model for how floating point types must be represented, and zero can
> always be represented exactly.


For those who don't know, Fred Tydeman specializes in concerns
related to floating-point arithmetic, and also is a long-standing
member of WG14 (I believe since its inception, but I'm not sure
about that). He may be the world's foremost authority on
floating point in ISO C; he certainly is among the group who
are candidates for that distinction.
 
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
How to count zeros in registers? Davy VHDL 39 12-05-2005 10:59 AM
Hexadecimal formatting with leading zeros?! Dmitry Bond. ASP .Net 1 10-13-2005 08:55 AM
Need help! I need to add lead zeros to a textbox Teep ASP .Net 2 06-21-2004 01:04 PM
Help! Need to add lead zeros to a textbox input TN Bella ASP .Net 6 06-21-2004 08:46 AM
Re: CSV for Excel - Problem with Leading Zeros Luke Zhang [MSFT] ASP .Net 0 06-26-2003 01:34 PM



Advertisments