Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #71022 > unrolled thread
| Started by | "Skybuck Flying" <skybuck2000@hotmail.com> |
|---|---|
| First post | 2015-09-21 20:17 +0200 |
| Last post | 2015-09-22 11:23 +0200 |
| Articles | 20 on this page of 145 — 21 participants |
Back to article view | Back to comp.lang.c
How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:17 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:43 +0200
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-21 19:51 +0100
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 23:26 +0200
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-21 22:47 +0100
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 16:29 +0200
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-22 16:11 +0100
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-23 11:18 +0200
Re: How to write this sign function in Delphi. David Brown <david.brown@hesbynett.no> - 2015-09-23 13:01 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:53 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:54 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:58 +0200
Re: How to write this sign function in Delphi. M Philbrook <jamie_ka1lpa@charter.net> - 2015-09-21 18:15 -0400
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-21 15:21 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-21 17:51 -0500
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-21 19:15 -0400
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-21 23:59 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-22 09:22 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-22 10:32 -0700
Re: How to write this sign function in Delphi. jt@toerring.de (Jens Thoms Toerring) - 2015-09-22 18:17 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-22 12:25 -0700
Re: How to write this sign function in Delphi. jt@toerring.de (Jens Thoms Toerring) - 2015-09-22 22:33 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-22 15:52 -0700
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-09-22 23:09 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-23 09:07 -0700
Re: How to write this sign function in Delphi. Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-09-23 16:55 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-23 10:46 -0700
Re: How to write this sign function in Delphi. jt@toerring.de (Jens Thoms Toerring) - 2015-09-23 23:18 +0000
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-23 22:29 -0400
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-24 11:09 +0100
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-27 18:23 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 05:20 +0000
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-27 23:23 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 09:03 +0100
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-28 01:24 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 09:32 +0100
Re: How to write this sign function in Delphi. Bartc <bc@freeuk.com> - 2015-09-28 10:22 +0100
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 11:35 +0100
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-28 10:33 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 18:59 +0100
Re: How to write this sign function in Delphi. Rosario19 <Ros@invalid.invalid> - 2015-09-28 20:09 +0200
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 13:39 -0500
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 20:04 +0100
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 16:43 -0500
Re: How to write this sign function in Delphi. Martin Shobe <martin.shobe@yahoo.com> - 2015-09-28 18:55 -0500
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 19:31 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-28 12:16 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-28 14:31 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 16:47 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-29 11:54 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-10-01 00:36 -0500
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-10-02 10:53 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-02 09:48 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-10-03 11:27 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 12:32 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-10-03 11:26 -0500
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-04 16:46 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-28 14:23 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 16:52 -0500
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-30 01:39 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-30 12:37 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-30 21:28 +0000
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-30 17:54 -0400
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-01 03:59 +0000
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-10-01 01:42 -0400
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-30 16:20 -0700
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-04 16:39 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 23:23 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-29 09:35 -0700
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-10-02 11:06 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-02 09:23 -0700
Re: How to write this sign function in Delphi. Martin Shobe <martin.shobe@yahoo.com> - 2015-10-02 12:07 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-02 10:47 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-10-02 17:48 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-10-03 16:46 +0100
Re: How to write this sign function in Delphi. Martin Shobe <martin.shobe@yahoo.com> - 2015-10-05 10:41 -0500
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-28 15:31 -0400
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 16:40 -0500
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-28 18:17 -0400
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-30 02:49 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-30 06:27 -0700
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-29 10:43 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 22:51 +0000
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-30 02:11 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 22:48 +0000
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 22:03 -0500
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-30 01:13 -0700
Re: How to write this sign function in Delphi. Bartc <bc@freeuk.com> - 2015-09-30 17:06 +0100
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-30 17:26 +0100
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-30 13:04 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 09:12 +0000
Re: How to write this sign function in Delphi. David Brown <david.brown@hesbynett.no> - 2015-09-28 12:28 +0200
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-28 20:44 +0100
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-01 01:39 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-10-01 08:55 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-01 09:02 -0700
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-01 14:55 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-01 16:48 -0700
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-10-02 11:46 +0000
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-06 00:15 -0700
Re: How to write this sign function in Delphi. Les Cargill <lcargill99@comcast.com> - 2015-10-06 02:43 -0500
Re: How to write this sign function in Delphi. David Brown <david.brown@hesbynett.no> - 2015-10-06 10:13 +0200
Re: How to write this sign function in Delphi. Les Cargill <lcargill99@comcast.com> - 2015-10-06 19:14 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 21:36 -0700
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-06 09:25 +0100
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 09:28 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-10-06 13:11 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 13:56 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-07 00:25 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 09:44 -0700
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-06 10:08 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 12:00 -0700
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-07 01:58 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-10-07 10:12 +0100
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-08 00:40 -0700
Re: How to write this sign function in Delphi. Philip Lantz <prl@canterey.us> - 2015-10-03 12:29 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 13:20 -0700
Re: How to write this sign function in Delphi. Philip Lantz <prl@canterey.us> - 2015-10-03 12:33 -0700
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-10-03 17:02 -0400
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 15:04 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-04 05:12 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-04 12:58 -0700
Re: How to write this sign function in Delphi. Philip Lantz <prl@canterey.us> - 2015-10-03 12:37 -0700
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-10-03 16:21 -0400
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 16:05 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 14:02 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-24 09:39 -0700
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-09-27 16:26 +0000
Re: How to write this sign function in Delphi. M Philbrook <jamie_ka1lpa@charter.net> - 2015-09-21 22:06 -0400
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-22 10:17 -0400
Re: How to write this sign function in Delphi. M Philbrook <jamie_ka1lpa@charter.net> - 2015-09-22 19:48 -0400
Re: How to write this sign function in Delphi. Noob <root@127.0.0.1> - 2015-09-23 13:15 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 21:25 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 21:54 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 22:02 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 21:50 +0200
Re: How to write this sign function in Delphi. M Philbrook <jamie_ka1lpa@charter.net> - 2015-09-21 18:08 -0400
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 08:31 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 10:18 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 10:50 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:00 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:07 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:20 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:15 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:23 +0200
Page 2 of 8 — ← Prev page 1 [2] 3 4 5 6 7 8 Next page →
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-09-22 12:25 -0700 |
| Message-ID | <d824189a-c5b8-4e09-80f4-80d8105dfdbe@googlegroups.com> |
| In reply to | #71104 |
On Tuesday, September 22, 2015 at 1:18:07 PM UTC-5, Jens Thoms Toerring wrote: > What would it actually be good for? When actually do you need to > right-shift signed integers? I've seen that done in two catego- > ries of code: one was very low level, platform dependent stuff, > where someone knew the behaviour of the underlying CPU and what > the compiler does very well (and thus had no trouble understanding > what the risks might be) and, on the other hand, in code by "cow- > boy" programmers that have some vague notion that bit-fiddling and > right-shifting would be faster than a division by a power of two, > and typically have no good idea what they are doing. Given a specification to write a formula to divide by 16 an integer x which is nowhere near INT_MAX, rounding to the nearest integer, but with exact half-way points rounded arbitrarily, can you suggest anything which is is clean, simple, and efficient as "(x+8)>>4"? Note that not only will "(x+8)/16" be far less efficient, but it will also fail badly if x is negative. In Python, the expression could be written as "(x+8)//16" since the "//" is a floored-integer-division operator rather than a comment delimiter, but C just has the far-less-useful truncating division operator. > Would it be necessary to change the standard (with all possible > unintended consequences) for the benefits of the second group, > just to avoid trouble for them when they falsely assume that a > right-shift is identlical to an integer division by 2? And that > at the cost that people using C for very hardware-near program- > ming now wouldn't be able anymore to exploit what the CPU is > actually doing in highly time-critical situations? Much of the usefulness of signed >> stems from the fact that, unlike the Fortran-derived "/" operator, it performs Euclidian division. While it might be nicer to have some alternative division operators for Euclidian or rounded division which use a specified divisor, and have a compiler recognize that it can optimize "x .ediv. 16" to use a right-shift, I know of no plans to add any such operator to the C language. > To me your proposal with macros and other kind of stuff (like > distinguishing between 1's and 2's complement architectures) > sounds actually a lot more complicated than remembering the > simple rule that you just don't shift signed integers - there > is no good reason for doing it I can see in everyday code (and > the assumption that it's faster is likely to be wrong - if a > division can be made faster by replacing it by a shift that's > one of the easiest things for an optimizing compiler). What would you suggest as a concise, efficient, readable, and portable way of performing a rounded division by 16 for all values that are no greater than INT_MAX-8? Note that there is no guarantee that any unsigned type has as many distinct values as "int" [it would be legitimate for a platform to define "int" as 64 value bits and a sign bit, and "unsigned long long" as 64 value bits and a padding bit], so I don't know of any strictly-conforming way to express the required operation which would not be bloated, hard to read, and unlikely to yield efficient machine code.
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2015-09-22 22:33 +0000 |
| Message-ID | <d6e3a7FtdpkU1@mid.uni-berlin.de> |
| In reply to | #71110 |
supercat@casperkitty.com wrote:
> On Tuesday, September 22, 2015 at 1:18:07 PM UTC-5, Jens Thoms Toerring wrote:
> > What would it actually be good for? When actually do you need to
> > right-shift signed integers? I've seen that done in two catego-
> > ries of code: one was very low level, platform dependent stuff,
> > where someone knew the behaviour of the underlying CPU and what
> > the compiler does very well (and thus had no trouble understanding
> > what the risks might be) and, on the other hand, in code by "cow-
> > boy" programmers that have some vague notion that bit-fiddling and
> > right-shifting would be faster than a division by a power of two,
> > and typically have no good idea what they are doing.
> Given a specification to write a formula to divide by 16 an integer x
> which is nowhere near INT_MAX, rounding to the nearest integer, but with
> exact half-way points rounded arbitrarily, can you suggest anything which
> is is clean, simple, and efficient as "(x+8)>>4"? Note that not only
> will "(x+8)/16" be far less efficient, but it will also fail badly if
> x is negative.
Why should it be less efficient?
? In Python, the expression could be written as "(x+8)//16"
> since the "//" is a floored-integer-division operator rather than a
> comment delimiter, but C just has the far-less-useful truncating division
> operator.
As far as I can see the Python3 '//' operator is just the C
integer division as in C (and behaves as the '/' operator in
Python2 when applied to integers).
> What would you suggest as a concise, efficient, readable, and portable way
> of performing a rounded division by 16 for all values that are no greater
> than INT_MAX-8?
Just do "(x+8)/16". If x is signed and the CPU can do
arithmetic right shifts I'd bet what the compiler will
produce is exactly the same as "(x+8)>>4" if an arith-
metic right-shif already is used for signed integers.
And if the CPU can't do arithmetic right-shifts natively
it will do just what you propose to add for right-shif-
ting of signed integers.
What I object to is giving the shift operators an arithmetic
meaning. They're for shifting sets of bits, not doing higher-
level calculations. They have such a meaning for certain types
due to the way these values are typically represented. But what
you seem to propose is to force this (more or less accidental)
meaning back onto the shift operations. When that's done, why
not also have the shift operator apply to floats, making them
just a true shortcut for multiplication or division by powers
of 2?
For unsigned integers the standard clearly requires a logical
right shift. Many implementations seem to do arithmetic
right shifts for signed integers. It would indeed be nice
if there would be a way to request an arithmetic right shift.
But rquiring such a binding to the signed-ness of an integer
type is IMHO a bit dubious, especially given that it intro-
duces backward compatibility issues for programs that were
written under the knowledge that this is implementation de-
fined and rely on what the implementation defines. Then
better lets have something new, i.e. a new operator that
stands for an arithmetic right shift (and which also can be
applied to other types).
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-09-22 15:52 -0700 |
| Message-ID | <90931e75-99b5-49b0-8418-ce18ddd524ca@googlegroups.com> |
| In reply to | #71115 |
On Tuesday, September 22, 2015 at 5:34:06 PM UTC-5, Jens Thoms Toerring wrote: > supercat wrote: > > Note that not only > > will "(x+8)/16" be far less efficient, but it will also fail badly if > > x is negative. > > Why should it be less efficient? For the same reason that it fails badly--because when x is negative, x/16 is required to compute -(-x/16). While "x >> 4" can on many platforms be computed in one single-cycle instruction, "x / 16" requires that a compiler generate code like "(x+((x >> 31) & 15) >> 4". The extra term which the C Standard mandates that compilers add when using the division operator takes extra code and extra time to compute, while totally messing up the rounding behavior. > As far as I can see the Python3 '//' operator is just the C > integer division as in C (and behaves as the '/' operator in > Python2 when applied to integers). The division operator C defines the behavior with negative dividends such that x/y yields -(-x/y). The division operator in Python much more usefully defines behavior with negative dividends such that (x+y)/y = (x/y)+1. In C, -31/16 yields -1. In Python, it yields -2. > Just do "(x+8)/16". If x is signed and the CPU can do > arithmetic right shifts I'd bet what the compiler will > produce is exactly the same as "(x+8)>>4" if an arith- > metic right-shif already is used for signed integers. > And if the CPU can't do arithmetic right-shifts natively > it will do just what you propose to add for right-shif- > ting of signed integers. If x equals -39, then (x+8)/16 will yield -31/16, i.e. -1. > But rquiring such a binding to the signed-ness of an integer > type is IMHO a bit dubious, especially given that it intro- > duces backward compatibility issues for programs that were > written under the knowledge that this is implementation de- > fined and rely on what the implementation defines. The only compatibility problems would be with programs which were written for platforms which have some other meaning, and could be resolved by specifying that implementations were allowed to assign other meanings provided that they document such behavior and reject code which uses some standard means (not yet defined) of indicating that it requires sign- extending right-shift behavior.
[toc] | [prev] | [next] | [standalone]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2015-09-22 23:09 +0000 |
| Message-ID | <5601df7e.6396109@news.xs4all.nl> |
| In reply to | #71099 |
supercat@casperkitty.com wrote: > On Monday, September 21, 2015 at 6:15:24 PM UTC-5, James Kuyper wrote: > > For certain unportable assumptions about how x>>31 works for negative > > numbers, ... > > I really wish the C Standard would recognize categories of conformance > between "strictly conforming" [doesn't use any features beyond those which > the most perversely-designed implementation would be required to support] > and "conforming" [works as required in some dialect somewhere]. Conforming to what, though? _Your_ expectations? Why not mine? Richard
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-09-23 09:07 -0700 |
| Message-ID | <006598fc-cfd6-43d9-ac56-1272a143cf58@googlegroups.com> |
| In reply to | #71123 |
On Tuesday, September 22, 2015 at 6:09:14 PM UTC-5, Richard Bos wrote: > > I really wish the C Standard would recognize categories of conformance > > between "strictly conforming" [doesn't use any features beyond those which > > the most perversely-designed implementation would be required to support] > > and "conforming" [works as required in some dialect somewhere]. > > Conforming to what, though? _Your_ expectations? Why not mine? Well, for starters, how about behaviors supported by compilers representing at least some fraction of the total market share by some metric? If the market is totally dominated by compilers which support some construct, and if programs using that construct could be written more cleanly and efficiently than programs which don't use it, what benefit is there to encouraging people whose programs will never need to run on a platform that can't support the construct, to nonetheless refrain from using it?
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2015-09-23 16:55 +0000 |
| Message-ID | <slrnn05mcs.eij.grahn+nntp@frailea.sa.invalid> |
| In reply to | #71152 |
On Wed, 2015-09-23, supercat@casperkitty.com wrote: > On Tuesday, September 22, 2015 at 6:09:14 PM UTC-5, Richard Bos wrote: >> > I really wish the C Standard would recognize categories of conformance >> > between "strictly conforming" [doesn't use any features beyond those which >> > the most perversely-designed implementation would be required to support] >> > and "conforming" [works as required in some dialect somewhere]. >> >> Conforming to what, though? _Your_ expectations? Why not mine? > > Well, for starters, how about behaviors supported by compilers representing at > least some fraction of the total market share by some metric? > > If the market is totally dominated by compilers which support some construct, > and if programs using that construct could be written more cleanly and > efficiently than programs which don't use it, what benefit is there to > encouraging people whose programs will never need to run on a platform that > can't support the construct, to nonetheless refrain from using it? I haven't read this thread very carefully, but I'm negative to the idea. People know the rules poorly enough already; I wouldn't want it to be even more fuzzy by having different semantics in different dialects, /plus/ the semantics in the C implementations I use. The alternative seems rather simple: decide what your program needs and standard C cannot deliver. Then document it using static assertions and unit tests, so it won't compile without the right set of extra language features. (I should probably do so myself more often. Almost everyone assumes certain implementation-defined behavior.) /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-09-23 10:46 -0700 |
| Message-ID | <eea43af9-7b96-42b7-a341-3fff59cb84f0@googlegroups.com> |
| In reply to | #71153 |
On Wednesday, September 23, 2015 at 11:56:18 AM UTC-5, Jorgen Grahn wrote:
> I haven't read this thread very carefully, but I'm negative to the
> idea. People know the rules poorly enough already; I wouldn't want it
> to be even more fuzzy by having different semantics in different
> dialects, /plus/ the semantics in the C implementations I use.
In each group of statements, identify the one you consider to be offer the
best blend of clarity, conciseness, and expected efficiency:
1a. y = (x+8) >> 4;
1b. y = x < 0 ? (x-8) / 16 : (x+8) / 16;
// Assume "hash_power" is a uint32_t
2a. hash_power *= hash_power;
2b. hash_power *= 1u*hash_power;
3a. if (ptr >= start && ptr < start+size) ...
3b. int overlaps = 0;
for (int i=0; i<size; i++)
if (start+i == ptr) {overlaps=1; break; }
if (overlaps) ...
4a. int32_t x = (int32_t)(some_uint32_value);
4b. int32_t x = (some_uint32_value & 0x80000000) ?
(int32_t)(some_uint32_t value-0x80000000)-0x40000000-0x40000000 :
(int32_t)some_uint32_t value;
5a. rotated = (x >> y) | (x << (32-y));
5b. rotated = (x >> y) | (x << (-y) & 31);
>>
> The alternative seems rather simple: decide what your program needs
> and standard C cannot deliver. Then document it using static
> assertions and unit tests, so it won't compile without the right set
> of extra language features.
<<
That would be fine if there were a standardized means of testing for
extra language features. IMHO, such means is one of the biggest things
missing from C.
Unfortunately, I know of no set of assertions which would guarantee that
something like e.g. 4a above would work. So far as I can tell, it would
be perfectly legitimate for a compiler to document the behavior of a
uint32_t to int32_t conversion as yielding a two's-complement reduction
except when the value to be converted was 0xCAFEBABE in which case the
conversion would yield 8675309 (and then generate code which behaved in
that fashion). While it would be very odd for a platform which uses
two's-complement arithmetic (mandated for "int32_t") to perform type
conversions from "uint32_t" as anything other than a bit-for-bit assignment,
I don't think anything in the Standrad would forbid such treatment, nor
do I know any way by which a program can refuse to compile on any platform
which would do such a thing.
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2015-09-23 23:18 +0000 |
| Message-ID | <d6gqa0FjkhcU1@mid.uni-berlin.de> |
| In reply to | #71154 |
supercat@casperkitty.com wrote:
> On Wednesday, September 23, 2015 at 11:56:18 AM UTC-5, Jorgen Grahn wrote:
> > I haven't read this thread very carefully, but I'm negative to the
> > idea. People know the rules poorly enough already; I wouldn't want it
> > to be even more fuzzy by having different semantics in different
> > dialects, /plus/ the semantics in the C implementations I use.
> In each group of statements, identify the one you consider to be offer the
> best blend of clarity, conciseness, and expected efficiency:
> 1a. y = (x+8) >> 4;
> 1b. y = x < 0 ? (x-8) / 16 : (x+8) / 16;
If
assert( -1 >> 1 ) < 0 );
does not fail I guess you can be pretty sure that arithmetic shifts
are used for signed integers and your "(x+8)>>4" construct should
work.
> // Assume "hash_power" is a uint32_t
> 2a. hash_power *= hash_power;
> 2b. hash_power *= 1u*hash_power;
No idea what you want to check for here. Of course. squaring
the value of a uint32_t may overflow. Is the question what's
the result on an overflow causes by a multiplication?
> 3a. if (ptr >= start && ptr < start+size) ...
What's this one about?
> 3b. int overlaps = 0;
> for (int i=0; i<size; i++)
> if (start+i == ptr) {overlaps=1; break; }
> if (overlaps) ...
Also no idea what you aim at here. I can only guess that you
want to compare pointers to different objects - otherwise what's
the problem? And that makes, as far as I can see, no sense unless
you write something very hardware specific - and then you already
will know what that platform allows you to do.
> 4a. int32_t x = (int32_t)(some_uint32_value);
If the intention is that 'x' afterwards has the same value as
'some_uint32_value' then this is doomed to fail for some uint32_t
values since the standard requires that all positive integers of
a signed type fit into the corresponding unsigned type but, of
course, not also the other way round. What you are guaranteed
(I think) is that 'x' will contain a value that has the same bit
representation as 'some_uint32_value' (whatever that may buy you;-)
> 4b. int32_t x = (some_uint32_value & 0x80000000) ?
> (int32_t)(some_uint32_t value-0x80000000)-0x40000000-0x40000000 :
> (int32_t)some_uint32_t value;
No idea what you want to achieve here.
> 5a. rotated = (x >> y) | (x << (32-y));
> 5b. rotated = (x >> y) | (x << (-y) & 31);
What's the type of 'x' etc.?
> > The alternative seems rather simple: decide what your program needs
> > and standard C cannot deliver. Then document it using static
> > assertions and unit tests, so it won't compile without the right set
> > of extra language features.
> That would be fine if there were a standardized means of testing for
> extra language features. IMHO, such means is one of the biggest things
> missing from C.
> Unfortunately, I know of no set of assertions which would guarantee that
> something like e.g. 4a above would work. So far as I can tell, it would
> be perfectly legitimate for a compiler to document the behavior of a
> uint32_t to int32_t conversion
As far as I (think I) knpw there's nothing to document: with a
cast you simply tell that the bits in memory are to be interpreted
differently - according to the bit representation of the type cast
to (and the standard guarantees that the signed and unsigned versions
of a integer types use the exact same amount of memory). There's
nothing the compiler will (or should) do about that. If you want
to manipulate values by fiddling with their bit representations
you're in for a certain amount of pain if you wish to make it work
everywhere. What the compiler does is making sure that, when you
operate with bitwise operators, the ordering of the bits is the
same everywhere (so you don't have to worry about endianess issues)
but there's no "canonical" bit representation of the values of
signed or unsigned integers But tehre are only 1's and 2's com-
plement allowed) - or what a right-shift on a 'signed' qualified
type does.
> as yielding a two's-complement reduction
> except when the value to be converted was 0xCAFEBABE in which case the
> conversion would yield 8675309 (and then generate code which behaved in
> that fashion). While it would be very odd for a platform which uses
> two's-complement arithmetic (mandated for "int32_t"
Where is that mandated?
> ) to perform type
> conversions from "uint32_t" as anything other than a bit-for-bit assignment,
> I don't think anything in the Standrad would forbid such treatment, nor
> do I know any way by which a program can refuse to compile on any platform
> which would do such a thing.
Some of what you write seem to hint at the following question:
Even though signed and unsigned versions of an integer type are
required to have the same amount of memory as stated in 6.2.5.6
For each of the signed integer types, there is a corresponding
(but different) unsigned integer type (designated with the keyword
unsigned) that uses the same amount of storage (including sign
information) and has the same alignment requirements.
may some of the memory used for an unsigned integer type be used
for padding bits (which would make the range of values that can
be represented by the unsigned version of the type smaller than
that of the signed type?
I'm not a language lawyer and hadn't considered a negative answer
to be "legal" - my assumption until now was that an unsigned and a
signed type have exactly the same number of "valid" (i.e. no more
padding for an unsigned than for a signed integer type) bits and a
cast between the two just results in a different interpretation of
the bits the memory occupied (like the 'reinterpret_cast' in C++).
Perhaps that would be something for a thread of its own...
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-09-23 22:29 -0400 |
| Message-ID | <mtvn2u$f84$1@dont-email.me> |
| In reply to | #71158 |
On 09/23/2015 07:18 PM, Jens Thoms Toerring wrote:
> supercat@casperkitty.com wrote:
>> On Wednesday, September 23, 2015 at 11:56:18 AM UTC-5, Jorgen Grahn wrote:
>>> I haven't read this thread very carefully, but I'm negative to the
>>> idea. People know the rules poorly enough already; I wouldn't want it
>>> to be even more fuzzy by having different semantics in different
>>> dialects, /plus/ the semantics in the C implementations I use.
>
>> In each group of statements, identify the one you consider to be offer the
>> best blend of clarity, conciseness, and expected efficiency:
>
>> 1a. y = (x+8) >> 4;
>> 1b. y = x < 0 ? (x-8) / 16 : (x+8) / 16;
>
> If
>
> assert( -1 >> 1 ) < 0 );
>
> does not fail I guess you can be pretty sure that arithmetic shifts
> are used for signed integers and your "(x+8)>>4" construct should
> work.
That's plausible, though not guaranteed.
I think that 1b was meant to match the behavior he expected to get from
1a, even when 1a has undefined behavior. However, 1a and 1b both have
defined behavior for -8 <= x && x < 0, but have different values in that
range. Assuming a corrected version of 1b, on any platform for which his
expectations are correct, 1a and a corrected version of 1b are likely to
be translated to identical code, so I would expect the efficiency to be
the same.
>> // Assume "hash_power" is a uint32_t
>> 2a. hash_power *= hash_power;
>> 2b. hash_power *= 1u*hash_power;
>
> No idea what you want to check for here. Of course. squaring
> the value of a uint32_t may overflow. Is the question what's
> the result on an overflow causes by a multiplication?
In principle, because of the usual arithmetic conversions, the detailed
behavior of 2b depends upon whether or not UINT_MAX < UINT32_MAX.
However, the final result is the same as 2a, either way. So I'm not sure
what his point is.
>> 3a. if (ptr >= start && ptr < start+size) ...
>
> What's this one about?
It would seem to be a valid check for whether or not ptr points inside
the range [start, start+size). However, 6.5.8p5, which describes pointer
comparisons for order, says that "In all other cases, the behavior is
undefined." If ptr and start point into different array objects, none of
the cases listed before that sentence applies, rendering the behavior of
the program containing that code undefined.
>> 3b. int overlaps = 0;
>> for (int i=0; i<size; i++)
>> if (start+i == ptr) {overlaps=1; break; }
>> if (overlaps) ...
>
> Also no idea what you aim at here. I can only guess that you
> want to compare pointers to different objects - otherwise what's
> the problem?
The problem is that the above code is the only portable way to check
whether ptr points somewhere inside the range [start, start+size), and
it's far less efficient than 3a, especially if "size" is large. Pointer
comparisons for equality have defined behavior for all valid pointers,
including null pointers.
>> 4a. int32_t x = (int32_t)(some_uint32_value);
>
> If the intention is that 'x' afterwards has the same value as
> 'some_uint32_value' then this is doomed to fail for some uint32_t
> values since the standard requires that all positive integers of
> a signed type fit into the corresponding unsigned type but, of
> course, not also the other way round. What you are guaranteed
> (I think) is that 'x' will contain a value that has the same bit
> representation as 'some_uint32_value' (whatever that may buy you;-)
That's not guaranteed by the standard, which is his point.
>> 4b. int32_t x = (some_uint32_value & 0x80000000) ?
>> (int32_t)(some_uint32_t value-0x80000000)-0x40000000-0x40000000 :
>> (int32_t)some_uint32_t value;
>
> No idea what you want to achieve here.
According to the standard, the behavior of 4a is undefined when
some_uint32_max > INT32_MAX. However, on most modern systems, it
actually behaves in a way that is well understood and widely known. 4b
is intended to represent that behavior using code with standard-defined
behavior. It's sufficiently complicated that I don't want to bother
checking, but something like that expression would certainly have the
desired effect.
>> 5a. rotated = (x >> y) | (x << (32-y));
>> 5b. rotated = (x >> y) | (x << (-y) & 31);
>
> What's the type of 'x' etc.?
Presumably it's the same 'x' as above above.
>>> The alternative seems rather simple: decide what your program needs
>>> and standard C cannot deliver. Then document it using static
>>> assertions and unit tests, so it won't compile without the right set
>>> of extra language features.
>
>> That would be fine if there were a standardized means of testing for
>> extra language features. IMHO, such means is one of the biggest things
>> missing from C.
>
>> Unfortunately, I know of no set of assertions which would guarantee that
>> something like e.g. 4a above would work. So far as I can tell, it would
>> be perfectly legitimate for a compiler to document the behavior of a
>> uint32_t to int32_t conversion
>
> As far as I (think I) knpw there's nothing to document: with a
> cast you simply tell that the bits in memory are to be interpreted
> differently - according to the bit representation of the type cast
> to (and the standard guarantees that the signed and unsigned versions
> of a integer types use the exact same amount of memory).
No - in the cases he's mentioned, the behavior is simply undefined -
it's not defined as retaining the bit patterns. In general, C
conversions are value-preserving, which often also result in retaining
the bit pattern, but retaining the bitter pattern is not generally
required (and is often impossible: conversion of values other than 0 and
1 to _Bool, conversions involving floating point types, and conversion
of negative integer values to an unsigned type when NOT using 2's
complement for the signed integer type).
...
>> as yielding a two's-complement reduction
>> except when the value to be converted was 0xCAFEBABE in which case the
>> conversion would yield 8675309 (and then generate code which behaved in
>> that fashion). While it would be very odd for a platform which uses
>> two's-complement arithmetic (mandated for "int32_t"
>
> Where is that mandated?
"The typedef name intN_t designates a signed integer type with width N,
no padding bits, and a two’s complement representation." (7.20.1.1p1)
>> ) to perform type
>> conversions from "uint32_t" as anything other than a bit-for-bit assignment,
>> I don't think anything in the Standrad would forbid such treatment, nor
>> do I know any way by which a program can refuse to compile on any platform
>> which would do such a thing.
>
> Some of what you write seem to hint at the following question:
>
> Even though signed and unsigned versions of an integer type are
> required to have the same amount of memory as stated in 6.2.5.6
>
> For each of the signed integer types, there is a corresponding
> (but different) unsigned integer type (designated with the keyword
> unsigned) that uses the same amount of storage (including sign
> information) and has the same alignment requirements.
>
> may some of the memory used for an unsigned integer type be used
> for padding bits (which would make the range of values that can
> be represented by the unsigned version of the type smaller than
> that of the signed type?
In general, yes. For the exact-sized types like int32_t and uint32_t,
however, padding bits are not allowed (see citation above). Therefore, a
bit-preserving conversion from uint32_t to int32_t is always possible -
but the standard does not mandate it.
I'm a portability expert, and therefore recognized almost all of the
issues he raised.. You're far from a newbie, but didn't recognize most
of them - and that's his point. It shouldn't require my level of
expertise to avoid these problems. However, there's a limit to how easy
it can be to master all of the portability issues of a language like C
that's intended to be *efficiently* implementable on almost every platform.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-09-24 11:09 +0100 |
| Message-ID | <87pp18f7sa.fsf@bsb.me.uk> |
| In reply to | #71159 |
James Kuyper <jameskuyper@verizon.net> writes: > On 09/23/2015 07:18 PM, Jens Thoms Toerring wrote: >> supercat@casperkitty.com wrote: <snip> >>> In each group of statements, identify the one you consider to be offer the >>> best blend of clarity, conciseness, and expected efficiency: <snip> >>> // Assume "hash_power" is a uint32_t >>> 2a. hash_power *= hash_power; >>> 2b. hash_power *= 1u*hash_power; >> >> No idea what you want to check for here. Of course. squaring >> the value of a uint32_t may overflow. Is the question what's >> the result on an overflow causes by a multiplication? > > In principle, because of the usual arithmetic conversions, the detailed > behavior of 2b depends upon whether or not UINT_MAX < UINT32_MAX. > However, the final result is the same as 2a, either way. So I'm not sure > what his point is. I think his point is that, in 2a, hash_power could promote to signed int and the arithmetic might therefore overflow. Much C is written with a hidden assumption that int is 32 bits (so uint32_t won't promote), or that integer overflow is harmless in that it will "wrap round" as so many processors now do. 2b is one idiom used to avoid making these assumptions, but it's not exactly self-evident code. The other one I've seen -- using a dummy ?: expression because C specifies that the usual arithmetic conversions are applied when the two arms have arithmetic types -- is even less self-evident but might be better just because you can't miss it! I think supercat makes some good points. C has all sorts of annoyances that make writing fast portable code hard, and he or she is clearly not just another of the "C should define everything like Java does" posters that pop up with such regularity. The rhetoric is a little off-putting "hyper-modern" optimiser for example!) and I don't agree with the rejection that an optimiser has a free hand with undefined code, but there are certainly places where C could be more helpful to the programmer or at least have fewer bear traps waiting for the unwary. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-09-27 18:23 -0700 |
| Message-ID | <9027a566-6b00-46c9-b3f0-157802a673ef@googlegroups.com> |
| In reply to | #71167 |
On Thursday, September 24, 2015 at 11:09:44 AM UTC+1, Ben Bacarisse wrote: > > Much C is written with a hidden assumption that int is 32 bits (so > uint32_t won't promote), or that integer overflow is harmless in that it > will "wrap round" as so many processors now do. > I think supercat makes some good points. C has all sorts of annoyances > that make writing fast portable code hard, and he or she is clearly not > just another of the "C should define everything like Java does" posters > that pop up with such regularity. > The vast majority of integers in most programs are indices, array sizes, or intermediate values used to calculate indices. Data is real if it represents a measurement of something in the physical world - not inherently so, it's just that most things we measure are continuous, and even things we count we tend to express as averages or percentage changes. If the data represents a human to human message, it's text. The major exception I can think of is data the represents amounts of money, really you need a currency type, especially because such data is likely to be attractive to criminals. (A scaled integer is, almost always, another representation of a real number. This point caused a lot of confusion a while ago.) So essentially the solution to the integer / overflow problem is to have a type that can index any array, and that traps on overflow conditions, because overflow has to represent either a coding bug, an attack, or a dataset too large for the program to handle. In all of those cases, you want to terminate the currently- executing function. Then you've got a few cases like hashing where you do need defined width types. And very low level routines where the integers are really flags which manipulate attached hardware. They're relatively rare, the fixed width types should be held back for special use.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-09-28 05:20 +0000 |
| Message-ID | <muaimh$93f$1@speranza.aioe.org> |
| In reply to | #71340 |
Malcolm McLean <malcolm.mclean5@btinternet.com> wrote: > On Thursday, September 24, 2015 at 11:09:44 AM UTC+1, Ben Bacarisse wrote: >> Much C is written with a hidden assumption that int is 32 bits (so >> uint32_t won't promote), or that integer overflow is harmless in >> that it will "wrap round" as so many processors now do. (snip) > The vast majority of integers in most programs are indices, > array sizes, or intermediate values used to calculate indices. > Data is real if it represents a measurement of something in > the physical world - not inherently so, it's just that most things > we measure are continuous, and even things we count we tend to > express as averages or percentage changes. Well, much of the real world is quantized according to quantum mechanics, though often in small enough steps that we can consider it continuous. There are some computation problems that really are integer, though you might still consider those like array access. Positions of characters of a bit image printer page are integers. > If the data represents > a human to human message, it's text. The major exception I can > think of is data the represents amounts of money, really you > need a currency type, especially because such data is likely to > be attractive to criminals. Two things that Knuth believe should always be done in fixed point are typesetting and finance. > (A scaled integer is, almost always, another representation of > a real number. This point caused a lot of confusion a while ago.) Usually fixed point is better for quantities that have absolute uncertainty, and floating point for relative uncertainty. > So essentially the solution to the integer / overflow problem > is to have a type that can index any array, and that traps on > overflow conditions, because overflow has to represent either a > coding bug, an attack, or a dataset too large for the program to > handle. In all of those cases, you want to terminate the currently- > executing function. With the assumption that the integer size is big enough for the things that you want to index. > Then you've got a few cases like hashing where you do need defined > width types. And very low level routines where the integers are > really flags which manipulate attached hardware. They're relatively > rare, the fixed width types should be held back for special use. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-09-27 23:23 -0700 |
| Message-ID | <89ce428f-9a14-4337-b529-59d0bb02b2ba@googlegroups.com> |
| In reply to | #71350 |
On Monday, September 28, 2015 at 6:20:32 AM UTC+1, glen herrmannsfeldt wrote: > Malcolm McLean <malcolm.mclean5@btinternet.com> wrote: > > There are some computation problems that really are integer, > though you might still consider those like array access. > Positions of characters of a bit image printer page are integers. > That's a marginal case. If you are setting up an N*M array in memory and then flushing it out to the printer in one go, it's an index. If you are feeding the printer sets of integer co-ordinates then I'd say no, it's best to think of it as integer data. Some data is integral, of course. If you're doing a traffic survey the data is likely to consist of whole numbers of cars, and you can think of other examples. But you usually only have a few such integers in a program, compared to hundreds of operations on arrays. > > Two things that Knuth believe should always be done in fixed > point are typesetting and finance. > The Federal Reserve is printing dollars like crazy at the moment. It's entirely possible that within a couple of years, the fixed point value will overflow at the price of a can of soda. Floating point gives you a bit more robustness. > > Usually fixed point is better for quantities that have absolute > uncertainty, and floating point for relative uncertainty. > But it's unusual for that to matter too much. A double is adequate for almost every calculation, and it's also a perfectly good integer type. You get 53 bits, and few counts will go above that. Fixed point is usually chosen for performance or implementation reasons, not because the step size is independent of magnitude. > > > So essentially the solution to the integer / overflow problem > > is to have a type that can index any array, and that traps on > > overflow conditions, because overflow has to represent either a > > coding bug, an attack, or a dataset too large for the program to > > handle. In all of those cases, you want to terminate the currently- > > executing function. > > With the assumption that the integer size is big enough for > the things that you want to index > That's crucial. You can't index more than fits in memory. But of course on a 16 bit or 32 bit system, maximum memory is usually 64K or 4GB, whilst the natural integer size is 16 bits or 32 bits. So, if you have an array of characters that occupies more than half total memory, you must index with an unsigned. So the unsigned size_t was born. But it's a complete nuisance, because whilst the more common case is stepping through an array from 0 to N-1, it is not at all unusual to need a negative for an intermediate. For example, if we're taking delta x; for(i=0;i<N-1;i++) delta[i] = x[i+1] - x[i]; if N is unsigned and zero, this will crash. Worse, that's a marginal special case which might well slip through testing.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-09-28 09:03 +0100 |
| Message-ID | <muas3u$2bh$1@dont-email.me> |
| In reply to | #71353 |
On 28/09/15 07:23, Malcolm McLean wrote: > On Monday, September 28, 2015 at 6:20:32 AM UTC+1, glen herrmannsfeldt wrote: >> Malcolm McLean <malcolm.mclean5@btinternet.com> wrote: >> >> There are some computation problems that really are integer, >> though you might still consider those like array access. >> Positions of characters of a bit image printer page are integers. >> > That's a marginal case. > If you are setting up an N*M array in memory and then flushing it out > to the printer in one go, it's an index. If you are feeding the printer > sets of integer co-ordinates then I'd say no, it's best to think > of it as integer data. > Some data is integral, of course. If you're doing a traffic survey > the data is likely to consist of whole numbers of cars, and you can > think of other examples. But you usually only have a few such > integers in a program, compared to hundreds of operations on > arrays. >> >> Two things that Knuth believe should always be done in fixed >> point are typesetting and finance. >> > The Federal Reserve is printing dollars like crazy at the moment. > It's entirely possible that within a couple of years, the fixed > point value will overflow at the price of a can of soda. > Floating point gives you a bit more robustness. Floating point is fine for roll-up calcs when you only have to be accurate to within (roughly) a millionth of a pound, but it's hopeless for keeping exact track of pennies. If a long int can't handle the amounts involved (or, if you're posh and up-to-date, a long long int), then you need bigger integers. Libraries exist that give you bigger integers, or you can of course roll your own. >> >> Usually fixed point is better for quantities that have absolute >> uncertainty, and floating point for relative uncertainty. >> > But it's unusual for that to matter too much. A double is adequate > for almost every calculation, and it's also a perfectly good integer > type. You get 53 bits, and few counts will go above that. If I am reading the Standard correctly, it only requires implementations to provide 32 bits for double, one of which is the sign bit and a few of which are needed for the exponent. So no, you aren't sure to get 53 bits. <snip> >> With the assumption that the integer size is big enough for >> the things that you want to index >> > [...] So the unsigned size_t was born. > But it's a complete nuisance, because whilst the more common > case is stepping through an array from 0 to N-1, it is not at > all unusual to need a negative for an intermediate. For example, > if we're taking delta x; > > for(i=0;i<N-1;i++) > delta[i] = x[i+1] - x[i]; > > if N is unsigned and zero, this will crash. Worse, that's a marginal > special case which might well slip through testing. Actually, it's a marginal special case that will be particularly highlighted by testing. Test cases are not chosen randomly (except, perhaps, when testing throughput). They are chosen specifically to highlight corner cases such as the above. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-09-28 01:24 -0700 |
| Message-ID | <e9c6eb98-7324-4485-9b34-d004f0d09177@googlegroups.com> |
| In reply to | #71357 |
On Monday, September 28, 2015 at 9:03:16 AM UTC+1, Richard Heathfield wrote: > On 28/09/15 07:23, Malcolm McLean wrote: > > > The Federal Reserve is printing dollars like crazy at the moment. > > It's entirely possible that within a couple of years, the fixed > > point value will overflow at the price of a can of soda. > > Floating point gives you a bit more robustness. > > Floating point is fine for roll-up calcs when you only have to be > accurate to within (roughly) a millionth of a pound, but it's hopeless > for keeping exact track of pennies. If a long int can't handle the > amounts involved (or, if you're posh and up-to-date, a long long int), > then you need bigger integers. Libraries exist that give you bigger > integers, or you can of course roll your own. > That's because you've been seduced by the idea that one dollar ten cents must be represented a 1.10. Represent as 110 cents instead. 2^53 gives us 90 trillion dollars - uncomfortably close to Obama's credit card amount outstanding. But if he borrows more than 90 trillon dollars, the number just loses a bit of accuracy. OK a fraudster can then maybe siphon off a thousand dollars or so from the American national accounts, but that's not a disaster in the big scheme of things.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-09-28 09:32 +0100 |
| Message-ID | <muatrp$8kg$1@dont-email.me> |
| In reply to | #71360 |
On 28/09/15 09:24, Malcolm McLean wrote: > On Monday, September 28, 2015 at 9:03:16 AM UTC+1, Richard Heathfield wrote: >> On 28/09/15 07:23, Malcolm McLean wrote: >> >>> The Federal Reserve is printing dollars like crazy at the moment. >>> It's entirely possible that within a couple of years, the fixed >>> point value will overflow at the price of a can of soda. >>> Floating point gives you a bit more robustness. >> >> Floating point is fine for roll-up calcs when you only have to be >> accurate to within (roughly) a millionth of a pound, but it's hopeless >> for keeping exact track of pennies. If a long int can't handle the >> amounts involved (or, if you're posh and up-to-date, a long long int), >> then you need bigger integers. Libraries exist that give you bigger >> integers, or you can of course roll your own. >> > That's because you've been seduced by the idea that one dollar ten cents > must be represented a 1.10. Er, no, I really haven't. > Represent as 110 cents instead. 2^53 > gives us 90 trillion dollars - uncomfortably close to Obama's > credit card amount outstanding. But you're not guaranteed 2^53 pennies. The Standard allows double to be as small as 32 bits. Take one for the sign bit. Even if you use *all* the remaining bits (which of course you can't), you would still only be able to represent a little over 2,000,000,000 pennies, which is a mere 200,000,000 principal currency units (be they pounds, dollars, or whatever). For some people (or indeed some currencies), that's small change. No, floating point Just Won't Do. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-09-28 10:22 +0100 |
| Message-ID | <mub0oi$ije$1@dont-email.me> |
| In reply to | #71361 |
On 28/09/2015 09:32, Richard Heathfield wrote: > On 28/09/15 09:24, Malcolm McLean wrote: >> Represent as 110 cents instead. 2^53 >> gives us 90 trillion dollars - uncomfortably close to Obama's >> credit card amount outstanding. > > But you're not guaranteed 2^53 pennies. The Standard allows double to be > as small as 32 bits. You'd be short-changed if you specified double and only got single-precision. Anyway where does it say that in the Standard? And even if it did say it, what is the likelihood of any C implementation on an actual computer (not some micro-controller) not giving you a 64-bit floating point type? Anyway this can easily be asserted. If we all took into account that double might only be 32-bits, then what is the point of having 64-bit doubles? -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-09-28 11:35 +0100 |
| Message-ID | <mub51i$23e$1@dont-email.me> |
| In reply to | #71364 |
On 28/09/15 10:22, Bartc wrote: > On 28/09/2015 09:32, Richard Heathfield wrote: >> On 28/09/15 09:24, Malcolm McLean wrote: > >>> Represent as 110 cents instead. 2^53 >>> gives us 90 trillion dollars - uncomfortably close to Obama's >>> credit card amount outstanding. >> >> But you're not guaranteed 2^53 pennies. The Standard allows double to be >> as small as 32 bits. > > You'd be short-changed if you specified double and only got > single-precision. Anyway where does it say that in the Standard? The float type can be as small as 32 bits (it /is/ 32 bits on the system I'm using right now) and the Standard does not require DBL_MAX to be greater than FLT_MAX or for DBL_MIN to be lower than FLT_MIN, so presumably it can fit into the same number of bits as a float. > And > even if it did say it, what is the likelihood of any C implementation on > an actual computer (not some micro-controller) not giving you a 64-bit > floating point type? I have no idea. I don't generally concern myself with data type sizes, because they vary between platforms, so I find it easier to work only within the guarantees provided by the Standard. > Anyway this can easily be asserted. > > If we all took into account that double might only be 32-bits, then what > is the point of having 64-bit doubles? Analogy: some bridges on the main UK road network can't take the strain of any vehicle with a laden weight greater than 7.5 tonnes. If you need to be able to cross any bridge, you need to keep the weight down. But if you're happy to stick to the more robust bridges (which, let's face it, is most of them), then you can carry heavier loads. So it's all about just how badly you need to be able to do your work *everywhere*. If portability is not a concern, there is no need to be concerned about portability. (Until, of course, the situation changes, by which time it's probably too late.) -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-09-28 10:33 -0700 |
| Message-ID | <lntwqesb25.fsf@kst-u.example.com> |
| In reply to | #71366 |
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 28/09/15 10:22, Bartc wrote:
>> On 28/09/2015 09:32, Richard Heathfield wrote:
>>> On 28/09/15 09:24, Malcolm McLean wrote:
>>
>>>> Represent as 110 cents instead. 2^53
>>>> gives us 90 trillion dollars - uncomfortably close to Obama's
>>>> credit card amount outstanding.
>>>
>>> But you're not guaranteed 2^53 pennies. The Standard allows double to be
>>> as small as 32 bits.
>>
>> You'd be short-changed if you specified double and only got
>> single-precision. Anyway where does it say that in the Standard?
>
> The float type can be as small as 32 bits (it /is/ 32 bits on the system
> I'm using right now) and the Standard does not require DBL_MAX to be
> greater than FLT_MAX or for DBL_MIN to be lower than FLT_MIN, so
> presumably it can fit into the same number of bits as a float.
Similar reasoning would imply that long can be as narrow as 16 bits.
The standard requires FLT_DIG to be at least 6, and DBL_DIG to
be at least 10. Both FLT_MAX and DBL_MAX are required to be at
least 1E+37.
6 decimal digits is about 20 bits, and 1E+37 is about 2**123, which
implies you need about 7 exponent bits, so float needs to be about
28 bits or more.
10 decimal digits is about 33 bits, so double needs to be about 41
bits or more.
I've undoubtedly made one or more off-by-one errors above, but not,
I think, enough to permit double to be represented in 32 bits.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-09-28 18:59 +0100 |
| Message-ID | <mubv24$d7g$1@dont-email.me> |
| In reply to | #71378 |
On 28/09/15 18:33, Keith Thompson wrote: > Richard Heathfield <rjh@cpax.org.uk> writes: >> On 28/09/15 10:22, Bartc wrote: >>> On 28/09/2015 09:32, Richard Heathfield wrote: >>>> On 28/09/15 09:24, Malcolm McLean wrote: >>> >>>>> Represent as 110 cents instead. 2^53 >>>>> gives us 90 trillion dollars - uncomfortably close to Obama's >>>>> credit card amount outstanding. >>>> >>>> But you're not guaranteed 2^53 pennies. The Standard allows double to be >>>> as small as 32 bits. >>> >>> You'd be short-changed if you specified double and only got >>> single-precision. Anyway where does it say that in the Standard? >> >> The float type can be as small as 32 bits (it /is/ 32 bits on the system >> I'm using right now) and the Standard does not require DBL_MAX to be >> greater than FLT_MAX or for DBL_MIN to be lower than FLT_MIN, so >> presumably it can fit into the same number of bits as a float. > > Similar reasoning would imply that long can be as narrow as 16 bits. Yes, I suppose so. :-) > The standard requires FLT_DIG to be at least 6, and DBL_DIG to > be at least 10. Both FLT_MAX and DBL_MAX are required to be at > least 1E+37. > > 6 decimal digits is about 20 bits, and 1E+37 is about 2**123, which > implies you need about 7 exponent bits, so float needs to be about > 28 bits or more. > > 10 decimal digits is about 33 bits, so double needs to be about 41 > bits or more. > > I've undoubtedly made one or more off-by-one errors above, but not, > I think, enough to permit double to be represented in 32 bits. I'll buy that. I did look at the Standard, of course, but as usual I found the FP stuff hard going. The important question in the present context is: what is the largest integer that double is required to be able to represent precisely, such that all smaller (positive) integers can also be represented? It was my belief that this number is considerably lower than 2^53, but it is now only my opinion. I don't quite see how to get the relevant number from the Linear B description of floating point provided in the Standard. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
Page 2 of 8 — ← Prev page 1 [2] 3 4 5 6 7 8 Next page →
Back to top | Article view | comp.lang.c
csiph-web