Topic: Hex floats
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 12 Dec 2002 22:47:24 +0000 (UTC) Raw View
kuyper@wizard.net ("James Kuyper Jr.") wrote
> Allan W wrote:
> > But why is "0.00000005p" preferable to
> > "0.00000000116415321826934814453" for (5 x 2**-32)?
>
> Well, for one thing, it can't be correct. 5*2**-32 = 5**33/10**32 =
> 0.00000000116415321826934814453125. You can tell that the previous one
> had to be wrong, because the numerator wasn't an exact power of 5.
Good point. I was relying on the Windows "Calculator" program, and
forgot to check for truncation.
> It's fine, functionally, but too indirect.
What do you mean by "indirect" and why is it a problem? AFAIK, most or
all optimizing compilers will solve this at compile-time, not run-time.
(Perhaps not some cross-platform compilers, but that's just a guess.)
I think that even if hex-floats make it into the standard, there will
be a lot of people that don't understand what it means. I think that
the explicit division method might make more sense, at least for
constants embedded directly in C++ code -- of course, when it comes
to text in a data file, I'm beginning to understand that there might
not be a good replacement for P notation.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Fri, 13 Dec 2002 05:13:45 +0000 (UTC) Raw View
Allan W wrote:
> kuyper@wizard.net ("James Kuyper Jr.") wrote
>
>>Allan W wrote:
>>
>>>But why is "0.00000005p" preferable to
>>>"0.00000000116415321826934814453" for (5 x 2**-32)?
>>
>>Well, for one thing, it can't be correct. 5*2**-32 = 5**33/10**32 =
>>0.00000000116415321826934814453125. You can tell that the previous one
>>had to be wrong, because the numerator wasn't an exact power of 5.
>
>
> Good point. I was relying on the Windows "Calculator" program, and
> forgot to check for truncation.
Which made a wonderful demonstration of the purpose of this feature.
Thanks! :-)
I used the unix 'bc' program, which is billed as an "arbitrary precision
calculator". I used it to calculate 5**33, and just threw in the right
number of 0s.
>>It's fine, functionally, but too indirect.
>
>
> What do you mean by "indirect" and why is it a problem? AFAIK, most or
It's too indirect because it relies on two separate constants and an
operation to achieve what can be better done by allowing a different
syntax on constant.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: walternospamm@digitalmars.nospaam.com ("Walter")
Date: Wed, 11 Dec 2002 19:53:24 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message
news:1039186425.7652@master.nyc.kbcfp.com...
> I don't have the book in front of me, but I believe that in _Software
> Manual for the Elementary Functions_ by Cody & Waite, which was at
> least once upon a time the bible for implementing trigonometric and
> exponential functions properly, certain of the algorithms require
> extremely precise numeric constants. The authors recommend that if
> possible, they should be written in hexadecimal to make sure that
> they are correct to the last bit, and they give a table of constants
> in this way.
That book relied on "Computer Approximations" by Hart. Hart gives a table in
the back with many floating point numbers in octal, so that there's no doubt
about the bit pattern. Hex constants come in handy for bootstrapping
strtold(), for example, getting the power of 10 table exactly right:
0x18.4f03e93ff9f4daa797ed6e38ed64bf6a1f01p+208L,
0x4.ee2d6d415b85acef81p+104L,
0x23.86f26fc1p+48L,
0x5.f5e1p+24L,
0x27.10p+8L,
0x64.p+0L,
0xa.p+0L,
Doing it in hex ensures the correct value, right down to the correct
rounding of the last representable bit.
Another place where hex floats come in handy is in float.h (excerpt from the
Digital Mars float.h):
#define DBL_EPSILON 0x1p-52
#define DBL_MAX 0x1.FFFFFFFFFFFFFp1023
#define DBL_MIN 0x1p-1022
#define FLT_MAX 0x1.FFFFFEp+127
#define FLT_MIN 0x1p-126
The values can be visually inspected to be correct, rather than a random
looking sequence of digits.
-Walter
www.digitalmars.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Dec 2002 21:18:12 +0000 (UTC) Raw View
Walter wrote:
> for example, getting the power of 10 table exactly right:
> 0x18.4f03e93ff9f4daa797ed6e38ed64bf6a1f01p+208L,
...
> #define DBL_MAX 0x1.FFFFFFFFFFFFFp1023
> The values can be visually inspected to be correct,
> rather than a random looking sequence of digits.
No comment :-)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: walternospamm@digitalmars.nospaam.com ("Walter")
Date: Thu, 12 Dec 2002 01:58:49 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message
news:1039638155.226414@master.nyc.kbcfp.com...
> Walter wrote:
> > for example, getting the power of 10 table exactly right:
> > 0x18.4f03e93ff9f4daa797ed6e38ed64bf6a1f01p+208L,
> ...
> > #define DBL_MAX 0x1.FFFFFFFFFFFFFp1023
> > The values can be visually inspected to be correct,
> > rather than a random looking sequence of digits.
>
> No comment :-)
LOL. A friend of mine in college wrote a program to calculate pi to 1000
decimal places. After printing out the results, he indicated he was pleased
with the results. I asked him how he knew it was producing the right answer.
He says, just look at it! (Turns out in high school he had memorized pi to
700 places or so, and so simply knew what the right digits were.)
-Walter
www.digitalmars.com Free C/C++/D compilers
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Thu, 12 Dec 2002 19:50:21 +0000 (UTC) Raw View
Allan W wrote:
> hyrosen@mail.com (Hyman Rosen) wrote
>
>>2**-N can be written exactly in N decimal digits and in
>>ceil(N/4) hexadecimal digits.
>
>
> You're right.
>
> But why is "0.00000005p" preferable to
> "0.00000000116415321826934814453" for (5 x 2**-32)?
Well, for one thing, it can't be correct. 5*2**-32 = 5**33/10**32 =
0.00000000116415321826934814453125. You can tell that the previous one
had to be wrong, because the numerator wasn't an exact power of 5.
> Are you worried about how many lines of source code are used?
>
> And what's wrong with "5.0/0x10000000" ?
It's fine, functionally, but too indirect.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Wed, 11 Dec 2002 03:31:25 +0000 (UTC) Raw View
Allan W wrote:
>>Hyman Rosen wrote:
>>
>>>It is possible to write out the exact value of
>>>any binary floating point number in decimal.
>>
>
> kuyper@wizard.net ("James Kuyper Jr.") wrote
> [ It's true that decimal can represent any value that hex can represent, ]
>
>>But only at the cost of using 4 times as many decimal digits as
>>hexadecimal digits.
>
>
> ...Because log(16)/log(10) is approximately 4? (I get about 1.2).
No, because there's only one power of 2 in 10, and four powers of two in
16. You need 4 powers of 10 to have a number that can be divided exactly
by 16. Therefore, to represent 1/16 exactly in decimal requires four
digits: 0.0625. To represent 5/256 exactly in decimal requires 8 digits:
0.01953125, etc..
> In any case, follow that logic to it's ultimate conclusion.
....
> By your logic, we should always prefer the hex version -- ignoring the
> radix-specifier, the hex digits are always equal or shorter than the
> decimal digits.
That point seems less foolish once you understand that the factor is
indeed 4, and not 1.2. However, that wasn't actually my main point.
My main point was that a hexadecimal floating point constant can
simultaneously
1. represent exactly the value that gets loaded into memory
2. Be the best possible representation, of it's length, of the actual
number you want to it to be.
In general, that's not true for decimal floating point constants, simply
because of those powers of 5 in the denominator of the corresponding
fraction.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 11 Dec 2002 10:07:51 CST Raw View
hyrosen@mail.com (Hyman Rosen) wrote
> 2**-N can be written exactly in N decimal digits and in
> ceil(N/4) hexadecimal digits.
You're right.
But why is "0.00000005p" preferable to
"0.00000000116415321826934814453" for (5 x 2**-32)?
Are you worried about how many lines of source code are used?
And what's wrong with "5.0/0x10000000" ?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Dec 2002 18:22:59 +0000 (UTC) Raw View
Allan W wrote:
> Are you worried about how many lines of source code are used?
I think mostly people are worried that their compiler or
input routines don't know how to generate the closest
floating point number to the decimal representation, and
don't know how to generate correct decimal versions of
their floating point numbers. Most of this discussion is
motivated by these sorts of fears, probably not unjustified.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Mon, 9 Dec 2002 18:12:49 +0000 (UTC) Raw View
James Kuyper Jr. wrote:
> Dave Harris wrote:
>
>> hyrosen@mail.com (Hyman Rosen) wrote (abridged):
>>
>>>> 0X1.23ef53ab21P312
>>>
>>>
>>> Glurg. What a bunch of line noise.
Agreed, but it's really for computer-generated data.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 5 Dec 2002 21:36:45 +0000 (UTC) Raw View
> James Kuyper Jr. wrote:
> > Hexadecimal floating point constants are allowed in C99. The syntax is
> > as follows:
> >
> > 0X1.23ef53ab21P312
hyrosen@mail.com (Hyman Rosen) wrote
> Glurg. What a bunch of line noise. In Ada, one could write
>
> 16#1.23EF5_3AB21#E312
I'm so glad that you brought that up, because I think it's important that
we keep our hexadecimal floating point constants readable.
I've been thinking a lot lately about hexadecimal floating point constants.
(That phrase is getting tiring -- let's abbreviate it HFPC). As we all
know, omitting HFPCs was one of Stroustrup's greatest omissions -- in
fact, we can trace this serious error all the way back to Kernigan and
Ritchie's original C language, which was (like all other important
pieces of software in the real world) completed in a hurry, due to time
constraints.
Indeed, when one needs to hard-code a floating point value into a piece
of software, one needs to be able to express it as closely as possible
in the original problem domain. Anyone who has ever written a business
application has needed not only decimal constants, but also HFPC for
such obvious and mundane tasks as (note to self -- think of some and
add them here before sending). So we can see how strong the need is.
But even more strongly than business applications, the real strength
of HFPC shines through when we use floating-point variables to contain
non-float data. For instance, we all know that
reinterpret_cast<long>(16#1.23EF5_3AB21#E312)
would obviously translate into the extremely useful bit pattern...
...okay, that's a bad example, because the format of float is
implementation-defined, so any bit pattern for the expression above
is non-portable.
That doesn't make it useless, though. One really obvious example would
be during debugging. Suppose your program crashes and gives you a core
dump. If the printout showed that a floating-point number contained the
hex value 1F2044F8, it might not be obvious what the actual float value
was. But using the magic of the debugger, you could simply enter this
value into a register and observe the results immediately.
...except you wouldn't be using an HFPC for that, would you? If you
were, you'd have to know which bits were the mantissa and which were
the exponent, and you'd have to reformat the number into the correct
syntax. Whereas you could simply load the unformatted hex value into a
variable and examine the results.
For that matter, when was the last time that anybody actually printed
out a core dump? These days, it's simpler just to load the core dump into
a debugger, and then you can simply look at the float value directly,
without every having to copy it from computer to paper and back.
Come to think of it, I don't actually remember needing to translate
numbers from HFPC notation into decimal floating point notation. I was
always afraid that sales tax rates might change, and the new literature
would give me the HFPC value instead of the decimal notation. (3.Ep0
seems so much more convenient than 38.75e-01, don't you think? But not
unless the C and C++ compilers support it.) But they never did, possibly
because of this very concern about compatibility with C and C++
compilers. (One of the few cases where government actually seems to care
about the working man.) Also, calculators at the time were inferior to
the ones you can buy today... I'm sure that today, all of us have
calculators that can process floating-point values in hex.
Wow, I just realized -- I can't think of a single example where a
HFPC would have been more convenient than a mere Decimal Floating Point
Constant. Some sort of "brain slip" -- and boy, do I feel embarassed!
Still, my humiliation should not affect this conversation. After all,
just because I'm having some kind of a mind block doesn't mean that
all of you are going to have the same problem. Go ahead, show off.
Let's have 5 good examples of ways that HFPC would be more convenient
than the restrictive rules we currently have in place. Or one. One would
still be better than my embarassing result set.
Would somone please post ONE good example of code where HFPC would be
more convenient than bulky decimal ones?
Thank you, and my apologies for the brain-slip. I'm sure there are dozens
of everyday examples that I simply overlooked... The stock market? The
grocery store in Hexville California? Boy this is frustrating...
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Thu, 5 Dec 2002 23:44:55 +0000 (UTC) Raw View
James Kuyper Jr. wrote:
> John Nagle wrote:
>
>> C and C++ provide hex integers, but not hex floats.
>
>
> Hexadecimal floating point constants are allowed in C99. The syntax is
> as follows:
>
>
> 0X1.23ef53ab21P312
Good. That should go into C++, too.
Is I/O for hex floats specified?
Now to get the XML people on board.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Thu, 5 Dec 2002 23:51:50 +0000 (UTC) Raw View
Allan W wrote:
>>James Kuyper Jr. wrote:
>>
>>>Hexadecimal floating point constants are allowed in C99. The syntax is
>>>as follows:
>>>
>>>0X1.23ef53ab21P312
>>
>
> hyrosen@mail.com (Hyman Rosen) wrote
>
>>Glurg. What a bunch of line noise. In Ada, one could write
>>
>> 16#1.23EF5_3AB21#E312
....
> Would somone please post ONE good example of code where HFPC would be
> more convenient than bulky decimal ones?
Hexidecimal notation isn't about convenience, so I don't think it's
likely that anyone will be able to meet that challenge.
> Thank you, and my apologies for the brain-slip. I'm sure there are dozens
> of everyday examples that I simply overlooked... The stock market? The
> grocery store in Hexville California? Boy this is frustrating...
No, there aren't a lot of everyday examples; a need that came up
everyday wouldn't have waited until 1999 to be dealt with.
If FLOAT_RADIX is a power of 2, then the C99 standard requires that if
an HFPC can be represented exactly, it must be. Otherwise, floating
point constants may be represented the closest representable value, or
by EITHER of the two values adjacent to the closest representable value.
There's a reason for this difference. If FLOAT_RADIX is a power of 2,
then there's a simple, straightforward algorithm for directly
determining the corresponding binary representation. For decimal
floating point constants (DFCPs), the algorithm is more complicated.
Getting precisely the closest representable value is difficult; even
getting one of the two bracketing representable values is tricky, which
is why the C standard is more lenient than that.
The prototypical example of a use for HFPCs is when specifying a
floating point constant with lots of significant digits, such as pi. To
represent pi to the fullest possible precision on a given machine
requires more digits in decimal than hexidecimal, by a factor of roughly
log(16)/log(10). However, that's a trivial factor, it's not the reason
for this feature. The problem is that the value which gets loaded into
the floating point register is in general NOT precisely the one
specified by the DFPC. To represent exactly the value that is stored in
a floating point register requires roughly 4 times as many digits in a
DFPC as in a HFPC (except when FLOAT_RADIX is not a power of 2, but that
would be a mighty odd architecture in today's market).
This only matters for constants that have so many significant digits
that even the very last ulp matters, which basically means mathematical
constants like pi and e. It's of very little importance for ordinary
code, but some people want a closer connection between the code they
write and the way the computer actually works than you can achieve with
a DFPC.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Fri, 6 Dec 2002 00:59:14 +0000 (UTC) Raw View
John Nagle wrote:
> James Kuyper Jr. wrote:
>
>> John Nagle wrote:
>>
>>> C and C++ provide hex integers, but not hex floats.
>>
>>
>>
>> Hexadecimal floating point constants are allowed in C99. The syntax is
>> as follows:
>>
>>
>> 0X1.23ef53ab21P312
>
>
>
> Good. That should go into C++, too.
> Is I/O for hex floats specified?
Yes, in C99 you can printf("%a") to print hexadecimal floating point
character strings using lowercase letters, and "%A" to get uppercase
letters. strtod() is required to accept hexadecimal sequences. The
behavior of both scanf("%a") and scanf("%A") is defined in terms of
strtod(). All three accept uppercase and lowercase letters on input.
If FLOAT_RADIX is a power of 2 and no precision is specified for
printf("%a"), then the default precision is enough precision to
represent the value exactly. For scanf("%a"), if FLOAT_RADIX is a power
of 2, the conversion is required to be correctly rounded; something
which isn't required for "%f".
This applies to the whole printf/scanf family, and the strtod() family
as well.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: algrant@myrealbox.com (Al Grant)
Date: Fri, 6 Dec 2002 16:31:29 +0000 (UTC) Raw View
kuyper@wizard.net ("James Kuyper Jr.") wrote in message news:<3DEFDD84.8060901@wizard.net>...
> For decimal
> floating point constants (DFCPs), the algorithm is more complicated.
> Getting precisely the closest representable value is difficult; even
> getting one of the two bracketing representable values is tricky, which
> is why the C standard is more lenient than that.
So why isn't the C++ standard equally lenient? It has tighter
requirements than those of Standard C, with obvious implications for
implementing C++ using C as an intermediate language. Another example
is that if the decimal constant is exactly representable, C++ requires
it to be exactly represented, while C does not. This may affect
constants like 0.1e1. C++ requires the result of converting this
constant to be 1.0 (assuming 1.0 is representable) while C does not.
In fact the C++ requirements are basically those of Draft Standard C
circa 1988, which were loosened in C89: see a recent thread on
comp.std.c. Did the C++ committee work from a pre-standard version
of C or did they deliberately not carry over the Standard C requirements
because they didn't accept the C committee's arguments?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 6 Dec 2002 17:16:36 +0000 (UTC) Raw View
Allan W wrote:
> Would somone please post ONE good example of code where HFPC would be
> more convenient than bulky decimal ones?
I don't have the book in front of me, but I believe that in _Software
Manual for the Elementary Functions_ by Cody & Waite, which was at
least once upon a time the bible for implementing trigonometric and
exponential functions properly, certain of the algorithms require
extremely precise numeric constants. The authors recommend that if
possible, they should be written in hexadecimal to make sure that
they are correct to the last bit, and they give a table of constants
in this way.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Fri, 6 Dec 2002 19:42:12 +0000 (UTC) Raw View
James Kuyper Jr. wrote:
> John Nagle wrote:
>
>> James Kuyper Jr. wrote:
>>
>>> John Nagle wrote:
>>>
>>>> C and C++ provide hex integers, but not hex floats.
>>> Hexadecimal floating point constants are allowed in C99. The syntax
>>> is as follows:
>>> 0X1.23ef53ab21P312
>> Good. That should go into C++, too.
>> Is I/O for hex floats specified?
>
>
>
> Yes, in C99 you can printf("%a") to print hexadecimal floating point
> character strings using lowercase letters, and "%A" to get uppercase
> letters. strtod() is required to accept hexadecimal sequences. The
> behavior of both scanf("%a") and scanf("%A") is defined in terms of
> strtod(). All three accept uppercase and lowercase letters on input.
>
> If FLOAT_RADIX is a power of 2 and no precision is specified for
> printf("%a"), then the default precision is enough precision to
> represent the value exactly. For scanf("%a"), if FLOAT_RADIX is a power
> of 2, the conversion is required to be correctly rounded; something
> which isn't required for "%f".
>
> This applies to the whole printf/scanf family, and the strtod() family
> as well.
Good. That should go into the C++ standard. C++ will also
need stream syntax for this.
What this is all about, for the person who asked, is having
the ability to write out floats as text and get back EXACTLY what was
written, which is useful in some numeric work where repeatability
is important.
It's the XML people, and the subroutine-call-via-XML
people (i.e. .NET) who need this sort of thing. It's one
of those fussy little things that causes problems for serious
number-crunching.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 6 Dec 2002 20:22:20 +0000 (UTC) Raw View
John Nagle wrote:
> write out floats as text and get back EXACTLY what was written
It is possible to write out the exact value of
any binary floating point number in decimal.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Fri, 6 Dec 2002 21:54:44 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote (abridged):
> > 0X1.23ef53ab21P312
>
> Glurg. What a bunch of line noise.
That's partly because of the use of uppercase.
0x1.23ef53ab21p312
The lowercase "p" has a descender which makes it relatively easy to spot,
once you know to look for it.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 7 Dec 2002 10:01:26 +0000 (UTC) Raw View
> Allan W wrote:
> > Hexidecimal Floating Point Constant (HFPC)
kuyper@wizard.net ("James Kuyper Jr.") wrote
> decimal floating point constants (DFCPs)
That should probably be DFPCs.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Sat, 7 Dec 2002 10:02:13 +0000 (UTC) Raw View
Hyman Rosen wrote:
> John Nagle wrote:
>
>> write out floats as text and get back EXACTLY what was written
>
>
> It is possible to write out the exact value of
> any binary floating point number in decimal.
But only at the cost of using 4 times as many decimal digits as
hexadecimal digits.
Let's consider a hexadecimal representation of pi. When FLT_RADIX is a
power of 2, such a representation can correspond exactly to the
representable double value that comes closest to pi, and that
hexadecimal character string is also the closest representation of that
length to pi.
You can have one of those features, or the other, but not both, for a
decimal representation. If the digit string exactly represents the value
stored in a double, it cannot be the closest representation to pi with
that number of digits. If it is the closest representation to pi with
that number of digits, it can't represent exactly the value that is
stored in the computer.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Mon, 9 Dec 2002 00:30:36 +0000 (UTC) Raw View
Dave Harris wrote:
> hyrosen@mail.com (Hyman Rosen) wrote (abridged):
>
>>>0X1.23ef53ab21P312
>>
>>Glurg. What a bunch of line noise.
>
>
> That's partly because of the use of uppercase.
Yes, I would ordinarily never use mixed case like that in a hexadecimal
number (floating point or integral). I used it in this case simply to
emphasize that it was legal.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Mon, 9 Dec 2002 20:10:41 +0000 (UTC) Raw View
> Hyman Rosen wrote:
> > It is possible to write out the exact value of
> > any binary floating point number in decimal.
kuyper@wizard.net ("James Kuyper Jr.") wrote
[ It's true that decimal can represent any value that hex can represent, ]
> But only at the cost of using 4 times as many decimal digits as
> hexadecimal digits.
...Because log(16)/log(10) is approximately 4? (I get about 1.2).
In any case, follow that logic to it's ultimate conclusion.
For integral constants, there are obvious cases where hex is much better
than decimal, at least from the standpoint of writing understandable,
maintainable code:
bool isBit17Set(long value) { return (value & 131072) != 0; } // Ugly
bool isBit17Set(long value) { return (value & 0x20000) != 0; } // Less so
There are also cases where decimal is clearly much better than hex:
void showdistance(long meters) { // Ugly version
long scale;
std::string units;
if (meters<0x3E8) scale=1, units="";
else if (meters<0xF4240) scale=0x3E8, units="kilo";
else if (meters<0x3B9ACA00) scale=0xF4240, units="mega";
else scale=0x3B9ACA00, units="giga"
std::cout << (meters / scale) << " " << units << "meters\n";
}
void showdistance(long meters) { // Not as ugly
long scale;
std::string units;
if (meters<1000) scale=1, units="";
else if (meters<1000000) scale=1000, units="kilo";
else if (meters<1000000000) scale=1000000, units="mega";
else scale=1000000000, units="giga"
std::cout << (meters / scale) << " " << units << "meters\n";
}
By your logic, we should always prefer the hex version -- ignoring the
radix-specifier, the hex digits are always equal or shorter than the
decimal digits.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 9 Dec 2002 20:23:54 +0000 (UTC) Raw View
Allan W wrote:
> ...Because log(16)/log(10) is approximately 4? (I get about 1.2).
Because 2**-N can be written exactly in N decimal digits and in
ceil(N/4) hexadecimal digits.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Wed, 4 Dec 2002 20:12:07 +0000 (UTC) Raw View
John Nagle wrote:
> C and C++ provide hex integers, but not hex floats.
Hexadecimal floating point constants are allowed in C99. The syntax is
as follows:
0X1.23ef53ab21P312
The letters can be upper or lower case, and 'P' is used instead of 'E'
to mark off the exponent. An F or an L at the end can be used to make it
a float or long double constant, respectively, just as with ordinary
floating point numbers. The exponent is handled as a decimal integer,
but it represents a power of 2, rather than a power of 10. Unlike
decimal floating point numbers, the P is not optional, and there must be
at least one digit following the P.
If FLOAT_RADIX is a power of two, an implementation is required to
always correctly round it to the closest representable value.
Recommended practice is to produce a diagnostic message when a
hexadecimal floating point value cannot be represented exactly.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 4 Dec 2002 21:21:38 +0000 (UTC) Raw View
James Kuyper Jr. wrote:
> Hexadecimal floating point constants are allowed in C99. The syntax is
> as follows:
>
> 0X1.23ef53ab21P312
Glurg. What a bunch of line noise. In Ada, one could write
16#1.23EF5_3AB21#E312
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Daniel.Miller@tellabs.com ("Dan'l Miller")
Date: Wed, 4 Dec 2002 21:45:23 +0000 (UTC) Raw View
Ron Natalie wrote:
> "John Nagle" <nagle@animats.com> wrote in message news:3DDEEDDB.8090807@animats.com...
>
>> C and C++ provide hex integers, but not hex floats.
>>It would be useful to be able to write
>>
>>0x1.d for 1.75
>>
>>The part after the decimal point, like the part in front,
>>is a hex value
>
>
> It wouldn't be a decimal point, it would be a hexadecimal point.
The canonical superordinate term for "decimal point" is "radix point".
("Superordinate" is the linguistics term for what we call "superclass" or "base
class": a near-synonym which differs only in generality. A synonym for "car" is
"automobile", whereas a superordinate for "car" is "vehicle".)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: Mon, 25 Nov 2002 19:22:40 +0000 (UTC) Raw View
On Mon, 25 Nov 2002 18:57:50 +0000 (UTC), nagle@animats.com (John Nagle) wrote:
> C and C++ provide hex integers, but not hex floats.
>It would be useful to be able to write
>
> 0x1.d for 1.75
>
>The part after the decimal point, like the part in front,
>is a hex value. Thus, all binary mantissas can be represented
>exactly. Exponents on such numbers would presumably also be in hex.
>
> What brings this up is the growing tendency to represent
>data in XML text files. Floating point numbers, when converted
>from binary to decimal, don't convert back exactly. Writing
>out a floating point number as its internal representation
>exposes the internal representation of the machine. But
>a hex float would read back exactly as written.
>
> This comes up because of a graphics application that
>saves as XML. It's a problem that save and load changes
>values a little, because physical simulations of interesting
>problems are often chaotic. The low order bits actually
>matter. The effect is that when you save your stunt
>animation and reload, it comes out differently.
>
> This is more useful in the I/O library than in the
>language, although it might be useful in certain machine
>generated code.
>
> Comments?
Why doesn't more decimal digits suffice to preserve the numbers
to required precision?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 25 Nov 2002 19:58:28 +0000 (UTC) Raw View
John Nagle wrote:
> Floating point numbers, when converted from binary to decimal,
> don't convert back exactly.
Yes they do. Rather, there are a pair of complementary algorithms
involved. (a) Write out the shortest decimal representation of a
number which will convert back into that number. (b) Convert a
decimal representation of a number into its closet machine
representation.
Here are the references:
How to print floating-point numbers accurately
<http://doi.acm.org/10.1145/93542.93559>
<http://www.cs.indiana.edu/~burger/FP-Printing-PLDI96.pdf>
How to Read Floating Point Numbers Accurately
<http://citeseer.nj.nec.com/william90how.html>
Look up the 1990 SIGPLAN PLDI conference proceedings.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ron@sensor.com ("Ron Natalie")
Date: Tue, 26 Nov 2002 03:51:32 +0000 (UTC) Raw View
"John Nagle" <nagle@animats.com> wrote in message news:3DDEEDDB.8090807@animats.com...
> C and C++ provide hex integers, but not hex floats.
> It would be useful to be able to write
>
> 0x1.d for 1.75
>
> The part after the decimal point, like the part in front,
> is a hex value
It wouldn't be a decimal point, it would be a hexadecimal point.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Tue, 26 Nov 2002 03:51:42 +0000 (UTC) Raw View
In article <3DDEEDDB.8090807@animats.com>, John Nagle
<nagle@animats.com> wrote:
| C and C++ provide hex integers, but not hex floats.
| It would be useful to be able to write
|
| 0x1.d for 1.75
|
| The part after the decimal point, like the part in front,
| is a hex value. Thus, all binary mantissas can be represented
| exactly. Exponents on such numbers would presumably also be in hex.
C99 introduced almost exactly what you propose. The exponent is a
decimal number representing the exponent of base 2. The exponent is
also not optional. 1.75 is written as 0x1.cP0
I share your hope that this valuable language addition make it into C++.
--
Howard Hinnant
Metrowerks
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: algrant@myrealbox.com (Al Grant)
Date: Tue, 26 Nov 2002 15:36:14 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote in message news:<1038253735.542506@master.nyc.kbcfp.com>...
> John Nagle wrote:
> > Floating point numbers, when converted from binary to decimal,
> > don't convert back exactly.
>
> Yes they do. Rather, there are a pair of complementary algorithms
> involved. (a) Write out the shortest decimal representation of a
> number which will convert back into that number. (b) Convert a
> decimal representation of a number into its closet machine
> representation.
But how do you do (b) portably in C++? Your implementation is
free to chose the next higher or next lower representable value,
not necessarily the closest of those two.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 26 Nov 2002 17:59:57 +0000 (UTC) Raw View
Al Grant wrote:
> But how do you do (b) portably in C++?
You don't need to do it portably, you just need to do it.
Hopefully, your implementation will already do it for you,
but if not, you get it done any way you can.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Mon, 25 Nov 2002 18:57:50 +0000 (UTC) Raw View
C and C++ provide hex integers, but not hex floats.
It would be useful to be able to write
0x1.d for 1.75
The part after the decimal point, like the part in front,
is a hex value. Thus, all binary mantissas can be represented
exactly. Exponents on such numbers would presumably also be in hex.
What brings this up is the growing tendency to represent
data in XML text files. Floating point numbers, when converted
from binary to decimal, don't convert back exactly. Writing
out a floating point number as its internal representation
exposes the internal representation of the machine. But
a hex float would read back exactly as written.
This comes up because of a graphics application that
saves as XML. It's a problem that save and load changes
values a little, because physical simulations of interesting
problems are often chaotic. The low order bits actually
matter. The effect is that when you save your stunt
animation and reload, it comes out differently.
This is more useful in the I/O library than in the
language, although it might be useful in certain machine
generated code.
Comments?
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]