Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #138944 > unrolled thread
| Started by | chanrasjid@gmail.com |
|---|---|
| First post | 2018-12-23 03:02 -0800 |
| Last post | 2018-12-24 22:36 -0800 |
| Articles | 20 on this page of 62 — 17 participants |
Back to article view | Back to comp.lang.c
A final word on casting. chanrasjid@gmail.com - 2018-12-23 03:02 -0800
Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 12:11 +0000
Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 13:08 +0000
Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 14:43 +0000
Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 14:56 +0000
Re: A final word on casting. chanrasjid@gmail.com - 2018-12-23 07:08 -0800
Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 15:55 +0000
Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 16:07 +0000
Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-23 08:21 -0800
Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 17:56 +0000
Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 19:23 +0000
Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 20:12 +0000
Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-23 14:06 -0800
Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-28 09:34 -0800
Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-28 20:29 +0000
Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-28 15:07 -0800
Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-28 20:56 -0500
Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-29 09:22 -0800
Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2019-01-01 13:27 -0800
Re: A final word on casting. Bart <bc@freeuk.com> - 2019-01-02 01:07 +0000
Re: A final word on casting. Bart <bc@freeuk.com> - 2019-01-03 18:55 +0000
Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2019-01-03 22:27 -0500
Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-04 16:25 -0500
Re: A final word on casting. Ike Naar <ike@iceland.freeshell.org> - 2018-12-28 19:10 +0000
Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-28 12:33 -0800
Re: A final word on casting. "Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid> - 2018-12-23 14:11 -0800
Re: A final word on casting. Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-12-24 02:54 -0800
Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-24 03:24 -0800
Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-24 03:29 -0800
Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-24 03:45 -0800
Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-24 13:44 +0000
Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-24 08:51 -0500
Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-23 14:53 -0500
Re: A final word on casting. Robert Wessel <robertwessel2@yahoo.com> - 2018-12-24 09:39 -0600
Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-24 13:38 -0500
Re: A final word on casting. Manfred <noname@add.invalid> - 2018-12-23 21:22 +0100
Re: A final word on casting. Manfred <noname@add.invalid> - 2018-12-23 21:33 +0100
Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-23 10:56 -0500
Re: A final word on casting. Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> - 2018-12-23 17:18 +0100
Re: A final word on casting. Bart <bc@freeuk.com> - 2018-12-23 20:03 +0000
Re: A final word on casting. "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2018-12-28 14:47 -0500
Re: A final word on casting. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-12-23 12:24 +0000
Re: A final word on casting. Richard Damon <Richard@Damon-Family.org> - 2018-12-23 07:28 -0500
Re: A final word on casting. Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-28 07:50 -0800
Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-23 04:35 -0800
Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-23 04:42 -0800
Re: A final word on casting. fir <profesor.fir@gmail.com> - 2018-12-23 04:52 -0800
Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-23 10:28 -0500
Re: A final word on casting. Barry Schwarz <schwarzb@dqel.com> - 2018-12-23 11:39 -0800
Re: A final word on casting. Ike Naar <ike@iceland.freeshell.org> - 2018-12-24 07:56 +0000
Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 14:03 -0800
Re: A final word on casting. Barry Schwarz <schwarzb@dqel.com> - 2018-12-24 14:39 -0800
Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 14:50 -0800
Re: A final word on casting. Keith Thompson <kst-u@mib.org> - 2018-12-24 15:34 -0800
Re: A final word on casting. Keith Thompson <kst-u@mib.org> - 2018-12-24 15:23 -0800
Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 20:34 -0800
Re: A final word on casting. Keith Thompson <kst-u@mib.org> - 2018-12-24 14:52 -0800
Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 20:25 -0800
Re: A final word on casting. James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-12-24 17:52 -0500
Re: A final word on casting. luser droog <luser.droog@gmail.com> - 2018-12-24 21:27 -0800
Re: A final word on casting. luser droog <luser.droog@gmail.com> - 2018-12-24 21:39 -0800
Re: A final word on casting. chanrasjid@gmail.com - 2018-12-24 22:36 -0800
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-01-03 18:55 +0000 |
| Message-ID | <tUsXD.1964$gy2.1241@fx21.am4> |
| In reply to | #139348 |
On 02/01/2019 01:07, Bart wrote: > On 01/01/2019 21:27, Tim Rentsch wrote: >> A short followup... >> >> Mostly for my own education I knocked up an exactly rounding >> floating-point constant conversion routine, completely from >> scratch, no help from external libraries or anything of that >> sort. Time to implement was the better part of a morning, >> resulting in about 250 lines of code of which function bodies >> were 115 lines - average function length just over 6 lines, >> ranging up to 19 lines maximum, with a median of 3 lines. (That sounds somewhat unlikely - that there are as many functions shorter than 3 lines as there are over 3 lines.) >> Disclosures: handles decimal constants with optional E-type >> exponents, but not hex/binary style; does not do range checking >> or handle subnormals; uses multiple precision arithmetic but not >> arbitrary precision; conversion is to 'double' although routines >> for 'float' or 'long double' could use the same core routine and >> would probably take about only 10 additional lines each. > > I've since just made use of strtod() to do the conversion. Then I get > results (for the binary reps of parsed decimal floats in source code) > that much those of most other compilers including gcc. > > I hadn't been much bothered: floating point arithmetic is generally only > approximate, and a naive conversion from decimal to binary float might > be out by up to a couple of least significant bits, out of 53. But it > seemed important to match behaviour of other compilers. I found that if I used 80-bit floats, then I can get results that match those from strtod, and those produced by gcc. (That is, given 1000 random floating point numbers of varying precision and range in source code), the compiled binary pattern matches exactly. For this set of numbers...) So I'm not sure what that 1000 bits is for that has been mentioned. 80-bit floats have only an extra 11 bits of precision. (This is experimental and done via non-portable inline ASM, but it shows that it can be done with only a few extra precision bits. Since the discrepancy was only a couple of bits, this is not surprising.)
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2019-01-03 22:27 -0500 |
| Message-ID | <3pAXD.199851$e%3.151775@fx42.iad> |
| In reply to | #139396 |
On 1/3/19 1:55 PM, Bart wrote: > > I found that if I used 80-bit floats, then I can get results that match > those from strtod, and those produced by gcc. (That is, given 1000 > random floating point numbers of varying precision and range in source > code), the compiled binary pattern matches exactly. For this set of > numbers...) > > So I'm not sure what that 1000 bits is for that has been mentioned. > 80-bit floats have only an extra 11 bits of precision. > > (This is experimental and done via non-portable inline ASM, but it shows > that it can be done with only a few extra precision bits. Since the > discrepancy was only a couple of bits, this is not surprising.) > The 1000 bit value was someones calculation of the number of bits you needed to be computing in to get absolute exact rounding of a floating point number to double precision, i.e. the difference between the rounded representation and the exact value represented by the string is less than 0.50000000000000... ULP. I haven't looked up the math to compute that, and while at first thought it seems high, I am not so sure as to say it must be too high. 'Random' numbers may not get you anywhere close to the needed value, as you are looking for the pathalogical case which gets you to looking for a difference between something like .4999999999999999 and .50000000000 where that small difference affects the final rounding.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2019-01-04 16:25 -0500 |
| Message-ID | <q0oj0b$khc$1@dont-email.me> |
| In reply to | #139410 |
On 1/3/19 22:27, Richard Damon wrote: > On 1/3/19 1:55 PM, Bart wrote: >> >> I found that if I used 80-bit floats, then I can get results that match >> those from strtod, and those produced by gcc. (That is, given 1000 >> random floating point numbers of varying precision and range in source >> code), the compiled binary pattern matches exactly. For this set of >> numbers...) >> >> So I'm not sure what that 1000 bits is for that has been mentioned. >> 80-bit floats have only an extra 11 bits of precision. >> >> (This is experimental and done via non-portable inline ASM, but it shows >> that it can be done with only a few extra precision bits. Since the >> discrepancy was only a couple of bits, this is not surprising.) >> > > The 1000 bit value was someones calculation of the number of bits you > needed to be computing in to get absolute exact rounding of a floating > point number to double precision, i.e. the difference between the > rounded representation and the exact value represented by the string is > less than 0.50000000000000... ULP. > > I haven't looked up the math to compute that, and while at first thought > it seems high, I am not so sure as to say it must be too high. 'Random' > numbers may not get you anywhere close to the needed value, as you are > looking for the pathalogical case which gets you to looking for a > difference between something like .4999999999999999 and .50000000000 > where that small difference affects the final rounding. The most difficult case to handle is a decimal string representing a value that is almost exactly halfway between two representable values, when the current rounding mode is "round to nearest". Such a string must be processed until you can determine whether it's above, below, or equal to that half-way value. On my system, the smallest representable value greater than 1.0 is 1.0 + 2^-52, which can be represented exactly in decimal as 1.0000000000000002220446049250313080847263336181640625 The halfway point between that and 1.0 is therefore 1.00000000000000011102230246251565404236316680908203125 If you process a digit string that starts with "1.00000000000000011102230246251565404236316680908203124", there's no need to process any further, it's guaranteed that the closest representable value is 1.0. If you process a digit string that starts with "1.00000000000000011102230246251565404236316680908203125", as soon as you've processed that part of the string, you only need to check whether any of the subsequent digits is non-zero. If so, it rounds up to 1.0000000000000002220446049250313080847263336181640625 otherwise, it rounds however you handle the halfway value. If __STDC_IEC_559__ is pre#defined by the implementaiton, than the rules of IEC/ISO 60559 (== IEEE 754) apply, which require that the half-way point be rounded to set the last bit to 0, which would correspond to 1.0 in this case. Either way, there's never any need to store any data after processing the first 54 significant digits. Handling the first 54 digits might require storing a lot more than 80 bits (I'm not sure whether there's a shortcut that would allow it to be done using only a little more than 52 bits), but it requires a lot less than 1000+ bits. I can't imagine what the argument might be that calls for 1000+ bits - perhaps Tim can give us a citation of the relevant discussion he referred to? His description was not sufficiently detailed for me to locate the discussion using Google groups.
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2018-12-28 19:10 +0000 |
| Message-ID | <slrn3ld8q2ct99.95s.ike@iceland.freeshell.org> |
| In reply to | #138982 |
On 2018-12-23, Bart <bc@freeuk.com> wrote: > On 23/12/2018 17:56, Ben Bacarisse wrote: >> Bart <bc@freeuk.com> writes: > >>> How does "1.999999999999..." in source code end up as /exactly/ 2.0? >> >> Because the compiler is giving you the closest double to the number you >> wrote. > > You say that so glibly that anyone reading it would just it take at face > value. > > What it doesn't explain is how a compiler, presented with a complex set > of lossy calculations to arrive at that result, and armed only with the > same 64-bit set of binary floating point operations, actually achieves it. > > My own C compiler gets this answer, (exactly 2.0 rather than the next > value below which is, I believe, > 1.9999999999999997779553950749686919152736663818359375), but that is > largely by chance. Generally, floating point constants might differ from > mature compilers like gcc by one least significant bit. > >> If you are going to do numerical work, you would need to understand >> what's happening but it's much simpler, for me, to leave you puzzled. > > I know what's happening here. What I don't know is the approach needed > to turn a string of decimal digits into the closest possible ieee 64-bit > float value. One possible approach is to use strtod().
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2018-12-28 12:33 -0800 |
| Message-ID | <d0df0a3c-e4ca-400b-b57a-7bce010bdfb2@googlegroups.com> |
| In reply to | #139185 |
On Friday, December 28, 2018 at 2:10:44 PM UTC-5, Ike Naar wrote: > On 2018-12-23, Bart <bc@freeuk.com> wrote: > > On 23/12/2018 17:56, Ben Bacarisse wrote: > >> Bart <bc@freeuk.com> writes: > > > >>> How does "1.999999999999..." in source code end up as /exactly/ 2.0? > >> > >> Because the compiler is giving you the closest double to the number you > >> wrote. > > > > You say that so glibly that anyone reading it would just it take at face > > value. > > > > What it doesn't explain is how a compiler, presented with a complex set > > of lossy calculations to arrive at that result, and armed only with the > > same 64-bit set of binary floating point operations, actually achieves it. > > > > My own C compiler gets this answer, (exactly 2.0 rather than the next > > value below which is, I believe, > > 1.9999999999999997779553950749686919152736663818359375), but that is > > largely by chance. Generally, floating point constants might differ from > > mature compilers like gcc by one least significant bit. > > > >> If you are going to do numerical work, you would need to understand > >> what's happening but it's much simpler, for me, to leave you puzzled. > > > > I know what's happening here. What I don't know is the approach needed > > to turn a string of decimal digits into the closest possible ieee 64-bit > > float value. > > One possible approach is to use strtod(). That would be consistent with the recommended practice "The translation- time conversion of floating constants should match the execution-time conversion of character strings by library functions, such as strtod, given matching inputs suitable for both conversions, the same result format, and default execution-time rounding." (6.4.4.2p7). This is also a good idea since, as noted in footnote 76, "The specification for the library functions recommends more accurate conversion than required for floating constants (see 7.22.1.3)." 7.22.1.3 says: > Recommended Practice > > 8 If the subject sequence has the hexadecimal form, FLT_RADIX is not > a power of 2, and the result is not exactly representable, the > result should be one of the two numbers in the appropriate internal > format that are adjacent to the hexadecimal floating source value, > with the extra stipulation that the error should have a correct sign > for the current rounding direction. > > 9 If the subject sequence has the decimal form and at most DECIMAL_DIG > (defined in <float.h>) significant digits, the result should be > correctly rounded. If the subject sequence D has the decimal form > and more than DECIMAL_DIG significant digits, consider the two > bounding, adjacent decimal strings L and U, both having DECIMAL_DIG > significant digits, such that the values of L, D, and U satisfy > L ≤ D ≤ U. The result should be one of the (equal or adjacent) > values that would be obtained by correctly rounding L and U > according to the current rounding direction, with the extra > stipulation that the error with respect to D should have a correct > sign for the current rounding direction.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid> |
|---|---|
| Date | 2018-12-23 14:11 -0800 |
| Message-ID | <pvp15m$smq$1@dont-email.me> |
| In reply to | #138978 |
On 12/23/2018 9:56 AM, Ben Bacarisse wrote:
> Bart <bc@freeuk.com> writes:
>
>> On 23/12/2018 15:08, chanrasjid@gmail.com wrote:
>>> On Sunday, December 23, 2018 at 10:57:14 PM UTC+8, Ben Bacarisse wrote:
>>>> Bart <bc@freeuk.com> writes:
>>>>
>>>>> On 23/12/2018 13:08, Ben Bacarisse wrote:
>>>>>> Bart <bc@freeuk.com> writes:
>>>>>
>>>>>>> Try:
>>>>>>>
>>>>>>> printf("%d\n", (int)1.9999999999999999999999999999999);
>>>>>>>
>>>>>>> I seem to get the answer 2.
>>>>>>
>>>>>> Are you really puzzled by that?
>>>>>
>>>>> Actually, yes. It means that (int)1.something will usually be 1 but
>>>>> sometimes 2.
>>>>
>>>> At least you won't be puzzled any more.
>>
>> Don't be so sure.
>>
>>> I think it is reasonable. C gives the closest double to represent 1.999... and it is 2.0; So (int) x gives the integral part is "almost" official.
>>
>> How does "1.999999999999..." in source code end up as /exactly/ 2.0?
>
> Because the compiler is giving you the closest double to the number you
> wrote.
>
> That constant /could/ give a value less than two because C only requires
> the result to be either the closest double, or one of the two double
> values adjacent to the closest. I.e. C permits a little wiggle room for
> implementations (but the implementation must document what happens).
>
>> Try this program, which starts from 1.0 then successively ends 0.9,
>> 0.09, 0.009 etc to get progressively longer versions of 1.999...
>>
>> It gets closer and closer to 2.0, but is never exactly 2.0:
>
> If you are going to do numerical work, you would need to understand
> what's happening but it's much simpler, for me, to leave you puzzled. I
> am not at all sure you really want to understand. If I'm wrong, and
> this is a part of C you'd like to learn, I will gladly explain.
>
Usually, before I cast a real to an integer is run it through floor or
ceil depending on the output I am looking for.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2018-12-24 02:54 -0800 |
| Message-ID | <e7c60c93-f61b-418f-b0e1-0170f64e7687@googlegroups.com> |
| In reply to | #138978 |
On Sunday, December 23, 2018 at 5:56:46 PM UTC, Ben Bacarisse wrote: > Bart <bc@freeuk.com> writes: > > > Try this program, which starts from 1.0 then successively ends 0.9, > > 0.09, 0.009 etc to get progressively longer versions of 1.999... > > > > It gets closer and closer to 2.0, but is never exactly 2.0: > > If you are going to do numerical work, you would need to understand > what's happening but it's much simpler, for me, to leave you puzzled. I > am not at all sure you really want to understand. If I'm wrong, and > this is a part of C you'd like to learn, I will gladly explain. > In mathematical notation, 1.999... equals two, not two minus an infinitesimal. A good compiler will have a patch to make sure a literal resolves to the right value.
[toc] | [prev] | [next] | [standalone]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2018-12-24 03:24 -0800 |
| Message-ID | <860ec62c-5f88-48a4-911d-871576abaf39@googlegroups.com> |
| In reply to | #139012 |
W dniu poniedziałek, 24 grudnia 2018 11:54:52 UTC+1 użytkownik Malcolm McLean napisał: > On Sunday, December 23, 2018 at 5:56:46 PM UTC, Ben Bacarisse wrote: > > Bart <bc@freeuk.com> writes: > > > > > Try this program, which starts from 1.0 then successively ends 0.9, > > > 0.09, 0.009 etc to get progressively longer versions of 1.999... > > > > > > It gets closer and closer to 2.0, but is never exactly 2.0: > > > > If you are going to do numerical work, you would need to understand > > what's happening but it's much simpler, for me, to leave you puzzled. I > > am not at all sure you really want to understand. If I'm wrong, and > > this is a part of C you'd like to learn, I will gladly explain. > > > In mathematical notation, 1.999... equals two, not two minus an > infinitesimal. A good compiler will have a patch to make sure a literal > resolves to the right value. in my personal opinion im closer to opinion that 1.999999.. dont equals 2.0... btw as using bcd could be to much wasteful storing 0-999 on 10 bits fields seem not so wasteful, and that kind of float qould be usefull for doing arithmetic that you may define as "fixed point arithmetic on N decimal places" (where the n is like 15 (say 5*10bits = 15 places) that could be more useful for this kind of operiations that this binary encoding who bring such big errors when using decimal form..also if soemeone would need a float that is better compatible with binary integers he could also use something better than this ii877 or what is this name - probably such compatible form could be something like that: lowest 24 bits are say normal integer (unsigned) highest 31-bit is a signe the 7 bits from 24 to 30 is signed 7 bit integer describing the shift of a dot in thet main 24 bit integer
[toc] | [prev] | [next] | [standalone]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2018-12-24 03:29 -0800 |
| Message-ID | <450fcb78-9b02-4e42-8c17-3db0a88af632@googlegroups.com> |
| In reply to | #139013 |
W dniu poniedziałek, 24 grudnia 2018 12:24:44 UTC+1 użytkownik fir napisał: > W dniu poniedziałek, 24 grudnia 2018 11:54:52 UTC+1 użytkownik Malcolm McLean napisał: > > On Sunday, December 23, 2018 at 5:56:46 PM UTC, Ben Bacarisse wrote: > > > Bart <bc@freeuk.com> writes: > > > > > > > Try this program, which starts from 1.0 then successively ends 0.9, > > > > 0.09, 0.009 etc to get progressively longer versions of 1.999... > > > > > > > > It gets closer and closer to 2.0, but is never exactly 2.0: > > > > > > If you are going to do numerical work, you would need to understand > > > what's happening but it's much simpler, for me, to leave you puzzled. I > > > am not at all sure you really want to understand. If I'm wrong, and > > > this is a part of C you'd like to learn, I will gladly explain. > > > > > In mathematical notation, 1.999... equals two, not two minus an > > infinitesimal. A good compiler will have a patch to make sure a literal > > resolves to the right value. > > in my personal opinion im closer to opinion that 1.999999.. dont equals 2.0... > > btw as using bcd could be to much wasteful storing 0-999 on 10 bits fields seem not so wasteful, and that kind of float qould be usefull for doing arithmetic that you may define as "fixed* point arithmetic on N decimal places" *not fixed but floating (typo) > (where the n is like 15 (say 5*10bits = 15 places) > > that could be more useful for this kind of operiations that this binary encoding > who bring such big errors when using decimal form..also if soemeone would need > a float that is better compatible with binary integers he could also use something better than this ii877 or what is this name - probably such compatible form could be something like that: lowest 24 bits are say normal integer (unsigned) > highest 31-bit is a signe the 7 bits from > 24 to 30 is signed 7 bit integer describing the shift of a dot in thet main 24 bit integer
[toc] | [prev] | [next] | [standalone]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2018-12-24 03:45 -0800 |
| Message-ID | <b81cad6c-6d0d-4774-8beb-4c36b03fa5f8@googlegroups.com> |
| In reply to | #139014 |
one could yet consider using one bit for storing the information if this value is a result of exact operations or of it something was cutted... this coul somewhat work but im not sure if its worth a bit, probably may be worth in thiose bigger ones (64 bit)
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2018-12-24 13:44 +0000 |
| Message-ID | <87r2e7f39l.fsf@bsb.me.uk> |
| In reply to | #139012 |
Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes: > On Sunday, December 23, 2018 at 5:56:46 PM UTC, Ben Bacarisse wrote: >> Bart <bc@freeuk.com> writes: >> >> > Try this program, which starts from 1.0 then successively ends 0.9, >> > 0.09, 0.009 etc to get progressively longer versions of 1.999... >> > >> > It gets closer and closer to 2.0, but is never exactly 2.0: >> >> If you are going to do numerical work, you would need to understand >> what's happening but it's much simpler, for me, to leave you puzzled. I >> am not at all sure you really want to understand. If I'm wrong, and >> this is a part of C you'd like to learn, I will gladly explain. >> > In mathematical notation, 1.999... equals two, not two minus an > infinitesimal. A good compiler will have a patch to make sure a literal > resolves to the right value. Except you can't write 1.999... and most programming languages. You certainly can't in C, so instead C has a rule about what value should be picked based on what the programmer writes. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2018-12-24 08:51 -0500 |
| Message-ID | <0w5UD.95040$gU6.49594@fx33.iad> |
| In reply to | #139012 |
On 12/24/18 5:54 AM, Malcolm McLean wrote: > On Sunday, December 23, 2018 at 5:56:46 PM UTC, Ben Bacarisse wrote: >> Bart <bc@freeuk.com> writes: >> >>> Try this program, which starts from 1.0 then successively ends 0.9, >>> 0.09, 0.009 etc to get progressively longer versions of 1.999... >>> >>> It gets closer and closer to 2.0, but is never exactly 2.0: >> >> If you are going to do numerical work, you would need to understand >> what's happening but it's much simpler, for me, to leave you puzzled. I >> am not at all sure you really want to understand. If I'm wrong, and >> this is a part of C you'd like to learn, I will gladly explain. >> > In mathematical notation, 1.999... equals two, not two minus an > infinitesimal. A good compiler will have a patch to make sure a literal > resolves to the right value. > 1.999... only equals 2 if you have an infinite number of 9's, which you can't write in source code (C has no way to denote an infinitely repeating decimal part). The confusion was writing a decimal number that is clearly less than 2, that gets converted to the value 2 in the code, and the answer is that due to the finite precision of the floating point representation, with enough 9s at the end, 2.00000 is close enough to the value to be allowed, and even gets to the point where it is close enough to be the 'best' value. The fact that floating point values are approximations of real numbers, and keeping track of how accurate your answers are (or more precisely, keeping an estimate of your accuracy, as if you knew your error exactly you would be able to have an exact answer) is a tough job, but also often an important one.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2018-12-23 14:53 -0500 |
| Message-ID | <pJRTD.94984$gU6.40605@fx33.iad> |
| In reply to | #138967 |
On 12/23/18 10:55 AM, Bart wrote:
> On 23/12/2018 15:08, chanrasjid@gmail.com wrote:
>> On Sunday, December 23, 2018 at 10:57:14 PM UTC+8, Ben Bacarisse wrote:
>>> Bart <bc@freeuk.com> writes:
>>>
>>>> On 23/12/2018 13:08, Ben Bacarisse wrote:
>>>>> Bart <bc@freeuk.com> writes:
>>>>
>>>>>> Try:
>>>>>>
>>>>>> printf("%d\n", (int)1.9999999999999999999999999999999);
>>>>>>
>>>>>> I seem to get the answer 2.
>>>>>
>>>>> Are you really puzzled by that?
>>>>
>>>> Actually, yes. It means that (int)1.something will usually be 1 but
>>>> sometimes 2.
>>>
>>> At least you won't be puzzled any more.
>
> Don't be so sure.
>
>> I think it is reasonable. C gives the closest double to represent
>> 1.999... and it is 2.0; So (int) x gives the integral part is "almost"
>> official.
>
> How does "1.999999999999..." in source code end up as /exactly/ 2.0?
>
> Try this program, which starts from 1.0 then successively ends 0.9,
> 0.09, 0.009 etc to get progressively longer versions of 1.999...
>
> It gets closer and closer to 2.0, but is never exactly 2.0:
>
> #include <stdio.h>
>
> int main (void) {
> double a,b;
>
> a=1.0;
> b=0.9;
> for (int i=0; i<30; ++i) {
> a+=b;
> printf("a: %.24f, 2.0-a: %.10e, a%s2.0, (int)a: %d, b: %e\n",
> a, 2.0-a, (a==2.0?"==":"!="), (int)a, b);
> b/=10.0;
> }
> }
>
> So it appears to be either rounding deliberately applied by a C
> compiler, or a side-effect of how the calculation is actually done.
>
One issue is that by the standard, to achieve the specified accuracy,
the implementation isn't allowed to just simply get the value of the
places with a chain of multiplication by 0.1 (or division by 10.0), as
that may build up too much accumulated error (and the difference between
2.0 and the number just below it is a very small number, so tiny errors
might be important).
Instead I would expect something more like:
int main(void) {
double a, b, c;
a = 1.0;
b = 1.0;
for(int i = 0; i < 30; i++) {
a = 10 * a + 9;
b = 10 * b;
c = a/b;
printf("c: %.24f, 2.0-c: %.10e, c$s2.0, (int)c: %d b:%e\n",
c, 2.0-c, (c == 2.0) ? "==" : "!=", (int) c, b);
}
}
Since a and b will always hold an 'integral' value, until their
magnitude exceeds the precision that can be stored in a double, the only
round off will be in computing a/b
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2018-12-24 09:39 -0600 |
| Message-ID | <a6u12et49jgehl4ont9shhj521me5h3k2j@4ax.com> |
| In reply to | #138988 |
On Sun, 23 Dec 2018 14:53:57 -0500, Richard Damon
<Richard@Damon-Family.org> wrote:
>On 12/23/18 10:55 AM, Bart wrote:
>> On 23/12/2018 15:08, chanrasjid@gmail.com wrote:
>>> On Sunday, December 23, 2018 at 10:57:14 PM UTC+8, Ben Bacarisse wrote:
>>>> Bart <bc@freeuk.com> writes:
>>>>
>>>>> On 23/12/2018 13:08, Ben Bacarisse wrote:
>>>>>> Bart <bc@freeuk.com> writes:
>>>>>
>>>>>>> Try:
>>>>>>>
>>>>>>> printf("%d\n", (int)1.9999999999999999999999999999999);
>>>>>>>
>>>>>>> I seem to get the answer 2.
>>>>>>
>>>>>> Are you really puzzled by that?
>>>>>
>>>>> Actually, yes. It means that (int)1.something will usually be 1 but
>>>>> sometimes 2.
>>>>
>>>> At least you won't be puzzled any more.
>>
>> Don't be so sure.
>>
>>> I think it is reasonable. C gives the closest double to represent
>>> 1.999... and it is 2.0; So (int) x gives the integral part is "almost"
>>> official.
>>
>> How does "1.999999999999..." in source code end up as /exactly/ 2.0?
>>
>> Try this program, which starts from 1.0 then successively ends 0.9,
>> 0.09, 0.009 etc to get progressively longer versions of 1.999...
>>
>> It gets closer and closer to 2.0, but is never exactly 2.0:
>>
>> #include <stdio.h>
>>
>> int main (void) {
>> double a,b;
>>
>> a=1.0;
>> b=0.9;
>> for (int i=0; i<30; ++i) {
>> a+=b;
>> printf("a: %.24f, 2.0-a: %.10e, a%s2.0, (int)a: %d, b: %e\n",
>> a, 2.0-a, (a==2.0?"==":"!="), (int)a, b);
>> b/=10.0;
>> }
>> }
>>
>> So it appears to be either rounding deliberately applied by a C
>> compiler, or a side-effect of how the calculation is actually done.
>>
>
>One issue is that by the standard, to achieve the specified accuracy,
>the implementation isn't allowed to just simply get the value of the
>places with a chain of multiplication by 0.1 (or division by 10.0), as
>that may build up too much accumulated error (and the difference between
>2.0 and the number just below it is a very small number, so tiny errors
>might be important).
>
>Instead I would expect something more like:
>
>int main(void) {
> double a, b, c;
> a = 1.0;
> b = 1.0;
> for(int i = 0; i < 30; i++) {
> a = 10 * a + 9;
> b = 10 * b;
> c = a/b;
> printf("c: %.24f, 2.0-c: %.10e, c$s2.0, (int)c: %d b:%e\n",
> c, 2.0-c, (c == 2.0) ? "==" : "!=", (int) c, b);
> }
>}
>
>Since a and b will always hold an 'integral' value, until their
>magnitude exceeds the precision that can be stored in a double, the only
>round off will be in computing a/b
That is the usual approach. It also produces the strictest results
(the representable number closest to the literal) assuming that the
division operations follows that rule (any IEEE compliant FP
implementation will do so, but there have certainty been machines
where that's not the case).
The usual limit is when the numerator exceeds the available precision
of a double. The denominator is usually not the problem, since it
always contains a fair-sized power of two as a factor (and on binary
FP systems, that doesn't consume mantissa bits).
If you need to maintain high accuracy beyond that, it becomes more
challenging, although the above never really goes more than a couple
of ULPs astray until the input string gets considerably longer than
the nominal precision of a double. I suspect that in many cases
people have just ignored that.
But... you can divide the number into sections, each no wider than
the available precision. Then you can compute both the quotient and
rounding error for each section, and then work your way across
determining if the rounding error (roughly the remainder, slightly
cooked) for one section, plus the quotient for the next section
(possibly post-rounding correction itself), requires an increment in
the first section. That usually requires at least some understanding
of the FP model in use. You can use a similar approach to produce
accurate results on machines where division produces questionable
quotients.
Other approaches are possible as well. A simple, if slow, one is to
compute that with a bignum library, and then convert a (binary) scaled
quotient to the FP value. That will still require a rounding
adjustment, but it's easy to pick out of the remainder of the bignum
division.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2018-12-24 13:38 -0500 |
| Message-ID | <1J9UD.115584$4d4.8940@fx41.iad> |
| In reply to | #139026 |
On 12/24/18 10:39 AM, Robert Wessel wrote:
> On Sun, 23 Dec 2018 14:53:57 -0500, Richard Damon
> <Richard@Damon-Family.org> wrote:
>
>> On 12/23/18 10:55 AM, Bart wrote:
>>> On 23/12/2018 15:08, chanrasjid@gmail.com wrote:
>>>> On Sunday, December 23, 2018 at 10:57:14 PM UTC+8, Ben Bacarisse wrote:
>>>>> Bart <bc@freeuk.com> writes:
>>>>>
>>>>>> On 23/12/2018 13:08, Ben Bacarisse wrote:
>>>>>>> Bart <bc@freeuk.com> writes:
>>>>>>
>>>>>>>> Try:
>>>>>>>>
>>>>>>>> printf("%d\n", (int)1.9999999999999999999999999999999);
>>>>>>>>
>>>>>>>> I seem to get the answer 2.
>>>>>>>
>>>>>>> Are you really puzzled by that?
>>>>>>
>>>>>> Actually, yes. It means that (int)1.something will usually be 1 but
>>>>>> sometimes 2.
>>>>>
>>>>> At least you won't be puzzled any more.
>>>
>>> Don't be so sure.
>>>
>>>> I think it is reasonable. C gives the closest double to represent
>>>> 1.999... and it is 2.0; So (int) x gives the integral part is "almost"
>>>> official.
>>>
>>> How does "1.999999999999..." in source code end up as /exactly/ 2.0?
>>>
>>> Try this program, which starts from 1.0 then successively ends 0.9,
>>> 0.09, 0.009 etc to get progressively longer versions of 1.999...
>>>
>>> It gets closer and closer to 2.0, but is never exactly 2.0:
>>>
>>> #include <stdio.h>
>>>
>>> int main (void) {
>>> double a,b;
>>>
>>> a=1.0;
>>> b=0.9;
>>> for (int i=0; i<30; ++i) {
>>> a+=b;
>>> printf("a: %.24f, 2.0-a: %.10e, a%s2.0, (int)a: %d, b: %e\n",
>>> a, 2.0-a, (a==2.0?"==":"!="), (int)a, b);
>>> b/=10.0;
>>> }
>>> }
>>>
>>> So it appears to be either rounding deliberately applied by a C
>>> compiler, or a side-effect of how the calculation is actually done.
>>>
>>
>> One issue is that by the standard, to achieve the specified accuracy,
>> the implementation isn't allowed to just simply get the value of the
>> places with a chain of multiplication by 0.1 (or division by 10.0), as
>> that may build up too much accumulated error (and the difference between
>> 2.0 and the number just below it is a very small number, so tiny errors
>> might be important).
>>
>> Instead I would expect something more like:
>>
>> int main(void) {
>> double a, b, c;
>> a = 1.0;
>> b = 1.0;
>> for(int i = 0; i < 30; i++) {
>> a = 10 * a + 9;
>> b = 10 * b;
>> c = a/b;
>> printf("c: %.24f, 2.0-c: %.10e, c$s2.0, (int)c: %d b:%e\n",
>> c, 2.0-c, (c == 2.0) ? "==" : "!=", (int) c, b);
>> }
>> }
>>
>> Since a and b will always hold an 'integral' value, until their
>> magnitude exceeds the precision that can be stored in a double, the only
>> round off will be in computing a/b
>
>
> That is the usual approach. It also produces the strictest results
> (the representable number closest to the literal) assuming that the
> division operations follows that rule (any IEEE compliant FP
> implementation will do so, but there have certainty been machines
> where that's not the case).
>
> The usual limit is when the numerator exceeds the available precision
> of a double. The denominator is usually not the problem, since it
> always contains a fair-sized power of two as a factor (and on binary
> FP systems, that doesn't consume mantissa bits).
>
> If you need to maintain high accuracy beyond that, it becomes more
> challenging, although the above never really goes more than a couple
> of ULPs astray until the input string gets considerably longer than
> the nominal precision of a double. I suspect that in many cases
> people have just ignored that.
>
> But... you can divide the number into sections, each no wider than
> the available precision. Then you can compute both the quotient and
> rounding error for each section, and then work your way across
> determining if the rounding error (roughly the remainder, slightly
> cooked) for one section, plus the quotient for the next section
> (possibly post-rounding correction itself), requires an increment in
> the first section. That usually requires at least some understanding
> of the FP model in use. You can use a similar approach to produce
> accurate results on machines where division produces questionable
> quotients.
>
> Other approaches are possible as well. A simple, if slow, one is to
> compute that with a bignum library, and then convert a (binary) scaled
> quotient to the FP value. That will still require a rounding
> adjustment, but it's easy to pick out of the remainder of the bignum
> division.
>
If the goal is to convert a string to a double value, you can basically
stop when the numerator goes by the precision limit, as additional terms
can't really affect the final result (maybe affect which way would be
the preferred way to round). You could perhaps even do better
accumulating the values into an int64_t (if your double is 64 bits) and
then at the end convert and divide or convert while dividing, but in
this case you MUST terminate the accumulation before you overflow the 64
bit int.
If you want a higher precision result, you of course need a higher
precision accumulator (maybe int128_t or a bignum) and a higher
precision output format.
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2018-12-23 21:22 +0100 |
| Message-ID | <pvoqq0$1q9m$1@gioia.aioe.org> |
| In reply to | #138967 |
On 12/23/2018 4:55 PM, Bart wrote:
> On 23/12/2018 15:08, chanrasjid@gmail.com wrote:
>> On Sunday, December 23, 2018 at 10:57:14 PM UTC+8, Ben Bacarisse wrote:
>>> Bart <bc@freeuk.com> writes:
>>>
>>>> On 23/12/2018 13:08, Ben Bacarisse wrote:
>>>>> Bart <bc@freeuk.com> writes:
>>>>
>>>>>> Try:
>>>>>>
>>>>>> printf("%d\n", (int)1.9999999999999999999999999999999);
>>>>>>
>>>>>> I seem to get the answer 2.
>>>>>
>>>>> Are you really puzzled by that?
>>>>
>>>> Actually, yes. It means that (int)1.something will usually be 1 but
>>>> sometimes 2.
>>>
>>> At least you won't be puzzled any more.
>
> Don't be so sure.
>
>> I think it is reasonable. C gives the closest double to represent
>> 1.999... and it is 2.0; So (int) x gives the integral part is "almost"
>> official.
>
> How does "1.999999999999..." in source code end up as /exactly/ 2.0?
>
> Try this program, which starts from 1.0 then successively ends 0.9,
> 0.09, 0.009 etc to get progressively longer versions of 1.999...
>
> It gets closer and closer to 2.0, but is never exactly 2.0:
This is simply b falling below DBL_EPSILON before it can trigger a round
up on a.
>
> #include <stdio.h>
>
> int main (void) {
> double a,b;
>
> a=1.0;
> b=0.9;
> for (int i=0; i<30; ++i) {
> a+=b;
> printf("a: %.24f, 2.0-a: %.10e, a%s2.0, (int)a: %d, b: %e\n",
> a, 2.0-a, (a==2.0?"==":"!="), (int)a, b);
> b/=10.0;
> }
> }
>
> So it appears to be either rounding deliberately applied by a C
> compiler, or a side-effect of how the calculation is actually done.
>
No, this is simply the C parser (or whatever the relevant translation
part is called) converting the string 1.99999999999999999999999999 to
double by rounding to the nearest representable value.
Try the following:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
double a = strtod("1.99999999999999999999999", NULL);
printf("(int)%.24lf = %d\n", a, (int)a);
}
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2018-12-23 21:33 +0100 |
| Message-ID | <pvorfk$1t29$1@gioia.aioe.org> |
| In reply to | #138967 |
On 12/23/2018 4:55 PM, Bart wrote:
<snip>
> Try this program, which starts from 1.0 then successively ends 0.9,
> 0.09, 0.009 etc to get progressively longer versions of 1.999...
>
> It gets closer and closer to 2.0, but is never exactly 2.0:
>
> #include <stdio.h>
>
> int main (void) {
> double a,b;
>
> a=1.0;
> b=0.9;
> for (int i=0; i<30; ++i) {
> a+=b;
> printf("a: %.24f, 2.0-a: %.10e, a%s2.0, (int)a: %d, b: %e\n",
> a, 2.0-a, (a==2.0?"==":"!="), (int)a, b);
> b/=10.0;
> }
> }
Try this instead:
#include <stdio.h>
int main (void) {
double a,b;
a=9.0;
b=0.9;
for (int i=0; i<30; ++i) {
a+=b;
printf("a: %.24f, 10.0-a: %.10e, a%s10.0, (int)a: %d, b: %e\n",
a, 10.0-a, (a==10.0?"==":"!="), (int)a, b);
b/=10.0;
}
}
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2018-12-23 10:56 -0500 |
| Message-ID | <pvob78$3pe$1@dont-email.me> |
| In reply to | #138965 |
On 12/23/18 10:08, chanrasjid@gmail.com wrote:
> On Sunday, December 23, 2018 at 10:57:14 PM UTC+8, Ben Bacarisse wrote:
>> Bart <bc@freeuk.com> writes:
>>
>>> On 23/12/2018 13:08, Ben Bacarisse wrote:
>>>> Bart <bc@freeuk.com> writes:
>>>
>>>>> Try:
>>>>>
>>>>> printf("%d\n", (int)1.9999999999999999999999999999999);
>>>>>
>>>>> I seem to get the answer 2.
>>>>
>>>> Are you really puzzled by that?
>>>
>>> Actually, yes. It means that (int)1.something will usually be 1 but
>>> sometimes 2.
>>
>> At least you won't be puzzled any more.
>>
>> --
>> Ben.
>
> I think it is reasonable. C gives the closest double to represent 1.999... and it is 2.0; So (int) x gives the integral part is "almost" official.
"For decimal floating constants, and also for hexadecimal floating
constants when FLT_RADIX is not a power of 2, the result is either the
nearest representable value, or the larger or smaller representable
value immediately adjacent to the nearest representable value, chosen in
an implementation-defined manner." (6.4.4.2p3).
For that particular number, given the large number of 9's following the
1, on most systems 2.0 would be the nearest representable value. While
the standard permits that constant to represent either the larger or
smaller representable values adjacent to that value, I think it would be
a poor-quality implementation that represented that constant with any
value other than 2.0. Having (int)1.9999999999999999999999999999999 give
2 rather than 1 as a result is therefore certainly permissible behavior,
and is also the most likely result.
Note that "For hexadecimal floating constants when FLT_RADIX is a power
of 2, the result is
correctly rounded.", which gives the implementation less freedom than it
has when that case doesn't apply. That's one of the key reasons for
using hexadecimal floating constants.
[toc] | [prev] | [next] | [standalone]
| From | Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> |
|---|---|
| Date | 2018-12-23 17:18 +0100 |
| Message-ID | <5c1fb54f$0$24955$e4fe514c@textnews.kpn.nl> |
| In reply to | #138968 |
On 23-12-2018 16:56, James Kuyper wrote: > On 12/23/18 10:08, chanrasjid@gmail.com wrote: >> On Sunday, December 23, 2018 at 10:57:14 PM UTC+8, Ben Bacarisse wrote: My oh my.. So many final words. amazing !!
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2018-12-23 20:03 +0000 |
| Message-ID | <LSRTD.34968$8Q1.34738@fx14.am4> |
| In reply to | #138961 |
On 23/12/2018 14:43, Bart wrote:
> On 23/12/2018 13:08, Ben Bacarisse wrote:
>> Bart <bc@freeuk.com> writes:
>
>>> Try:
>>>
>>> printf("%d\n", (int)1.9999999999999999999999999999999);
>>>
>>> I seem to get the answer 2.
>>
>> Are you really puzzled by that?
>
> Actually, yes. It means that (int)1.something will usually be 1 but
> sometimes 2.
>
> (I tried my own language to see if it does something different, and that
> was worse as it seems to round to nearest int value [for x64 target
> using 'cvtsd2si'], so this effect happens when you try the equivalent of
> (int)1.4999999999999999999999.
(This rounding affected two of my compilers, including the C one. But
the fix was easy: gcc uses 'cvttsd2si' not 'cvtsd2si' (notice the extra
't'), which always rounds towards zero, so I did the same.
I think my languages used to round to nearest anyway so this might have
been normal behaviour, but it would simplify things if they followed the
same rules as C. In this case.)
--
bart
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web