Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #19901 > unrolled thread
| Started by | Xavier Roche <xroche@free.fr.NOSPAM.invalid> |
|---|---|
| First post | 2012-04-25 16:17 +0200 |
| Last post | 2012-04-26 14:49 +0000 |
| Articles | 6 — 5 participants |
Back to article view | Back to comp.lang.c
Cast from double to int64_t/uint64_t : +/- inf handling ? Xavier Roche <xroche@free.fr.NOSPAM.invalid> - 2012-04-25 16:17 +0200
Re: Cast from double to int64_t/uint64_t : +/- inf handling ? James Kuyper <jameskuyper@verizon.net> - 2012-04-25 11:37 -0400
Re: Cast from double to int64_t/uint64_t : +/- inf handling ? Xavier Roche <xroche@free.fr.NOSPAM.invalid> - 2012-04-26 10:54 +0200
Re: Cast from double to int64_t/uint64_t : +/- inf handling ? "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-04-26 06:09 -0700
Re: Cast from double to int64_t/uint64_t : +/- inf handling ? Tim Rentsch <txr@alumni.caltech.edu> - 2012-05-07 16:46 -0700
Re: Cast from double to int64_t/uint64_t : +/- inf handling ? "Fred J. Tydeman" <tydeman.consulting@sbcglobal.net> - 2012-04-26 14:49 +0000
| From | Xavier Roche <xroche@free.fr.NOSPAM.invalid> |
|---|---|
| Date | 2012-04-25 16:17 +0200 |
| Subject | Cast from double to int64_t/uint64_t : +/- inf handling ? |
| Message-ID | <jn911j$2cq$1@news.httrack.net> |
Hi folks, Are there any rules regarding cast result from double to int64_t/uint64_t for positive/negative infinity, or is the result totally undefined ? Typically, playing with cast on x86-64 arch (Linux/gcc) leads to the following observations: (uint64_t) -inf == 9223372036854775808 (8000000000000000) (uint64_t) inf == 0 (0) (int64_t) -inf == -9223372036854775808 (8000000000000000) (int64_t) inf == -9223372036854775808 (8000000000000000) (I was expecting (uint64_t) inf to give 0xffffffffffffffff for example) [ I could play with finite()/isinf(), but I was wondering if a fast method would be available/documented. ]
[toc] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-04-25 11:37 -0400 |
| Message-ID | <4F981A1D.90707@verizon.net> |
| In reply to | #19901 |
On 04/25/2012 10:17 AM, Xavier Roche wrote: > Hi folks, > > Are there any rules regarding cast result from double to > int64_t/uint64_t for positive/negative infinity, or is the result > totally undefined ? 6.3.1.4p1 defines the behavior when a finite value of real floating type is converted to an integer type; the behavior is undefined if the value cannot be represented in the integer type. Nothing defines the result when infinite values are converted, so the behavior is undefined "by omission of any explicit definition of behavior" (4p2). The same argument applies to NaNs. This fits into the general scheme of C conversions; they are value-preserving, to the extent that they can be, when the value being converted is within the representable range of the destination type, and usually have undefined behavior when it is not. The special handling of _Bool, and the modulo results when converting from integer values to unsigned types are the two main exceptions to that rule. C integer types don't have representations of infinities or NaNs (though it would be perfectly feasible to implement an integer-like type which did). > Typically, playing with cast on x86-64 arch (Linux/gcc) leads to the > following observations: > (uint64_t) -inf == 9223372036854775808 (8000000000000000) > (uint64_t) inf == 0 (0) > (int64_t) -inf == -9223372036854775808 (8000000000000000) > (int64_t) inf == -9223372036854775808 (8000000000000000) > > (I was expecting (uint64_t) inf to give 0xffffffffffffffff for example) > > [ I could play with finite()/isinf(), but I was wondering if a fast > method would be available/documented. ] To avoid undefined behavior, it is necessary to avoid converting any value that is greater than [U]INT64_MAX, or less than INT64_MIN (or less than 0 for uint64_t). Infinities will be captured by such checks, so there's no need for a separate check of isfinite() or isinf(). On the other hand, if NaNs are a possibility, you will need to check isnan().
[toc] | [prev] | [next] | [standalone]
| From | Xavier Roche <xroche@free.fr.NOSPAM.invalid> |
|---|---|
| Date | 2012-04-26 10:54 +0200 |
| Message-ID | <jnb2g5$2cq$2@news.httrack.net> |
| In reply to | #19904 |
On 04/25/2012 05:37 PM, James Kuyper wrote: > To avoid undefined behavior, it is necessary to avoid converting any > value that is greater than [U]INT64_MAX, or less than INT64_MIN (or less > than 0 for uint64_t). Makes sense, thanks for the exhaustive reply! [ I was hoping (at least on x86-64 archs) that the corresponding conversion would handle that, but this is not the case obviously ; the 0x8000000000000000 value returned is "the indefinite integer value" as per x86-64 convention BTW. ]
[toc] | [prev] | [next] | [standalone]
| From | "christian.bau" <christian.bau@cbau.wanadoo.co.uk> |
|---|---|
| Date | 2012-04-26 06:09 -0700 |
| Message-ID | <a5aba264-0248-46ca-abe5-2d8418391822@z17g2000yqf.googlegroups.com> |
| In reply to | #19904 |
On Apr 25, 4:37 pm, James Kuyper <jameskuy...@verizon.net> wrote: > To avoid undefined behavior, it is necessary to avoid converting any > value that is greater than [U]INT64_MAX, or less than INT64_MIN (or less > than 0 for uint64_t). Infinities will be captured by such checks, so > there's no need for a separate check of isfinite() or isinf(). On the > other hand, if NaNs are a possibility, you will need to check isnan(). But you need to be quite careful: If you check for example "if (x >= 0 && x <= UINT64_MAX)" then UINT64_MAX, likely 2^64 - 1, will be converted to double and rounded, likely producing 2^64, so a value of x == 2^64 will pass the test but give undefined behaviour when converted to uint64_t. On the other hand, if you test "if (x >= 0 && x < UINT64_MAX)" the test will fail if x has a 64 bit mantissa and x is exactly equal to 2^64 - 1 even though it can be converted (but usually double is 64 bits total with 53 bit mantissa so you would be fine). On the third hand, if (x < UINT64_MAX) fails then you know that x is quite large, so that might be enough information.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-05-07 16:46 -0700 |
| Message-ID | <kfntxzrzhaa.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #19904 |
James Kuyper <jameskuyper@verizon.net> writes: > On 04/25/2012 10:17 AM, Xavier Roche wrote: >> Hi folks, >> >> Are there any rules regarding cast result from double to >> int64_t/uint64_t for positive/negative infinity, or is the result >> totally undefined ? > > 6.3.1.4p1 defines the behavior when a finite value of real floating type > is converted to an integer type; the behavior is undefined if the value > cannot be represented in the integer type. [snip..snip..snip] > > To avoid undefined behavior, it is necessary to avoid converting any > value that is greater than [U]INT64_MAX, or less than INT64_MIN (or less > than 0 for uint64_t). [snip] Actually the values to avoid are >= [U]INT64_MAX + 1, or <= INT64_MIN-1, or <= -1 for uint64_t, because of such conversions doing truncation toward zero.
[toc] | [prev] | [next] | [standalone]
| From | "Fred J. Tydeman" <tydeman.consulting@sbcglobal.net> |
|---|---|
| Date | 2012-04-26 14:49 +0000 |
| Message-ID | <Jd11RFbi8Eoq-pn2-FTNb1YretdeN@localhost> |
| In reply to | #19901 |
On Wed, 25 Apr 2012 14:17:23 UTC, Xavier Roche <xroche@free.fr.NOSPAM.invalid> wrote: > Are there any rules regarding cast result from double to > int64_t/uint64_t for positive/negative infinity, or is the result > totally undefined ? If Annex F is being followed, the requirements are: F.4 Floating to integer conversion If the integer type is _Bool, 6.3.1.2 applies and no floating-point exceptions are raised (even for NaN). Otherwise, if the floating value is infinite or NaN or if the integral part of the floating value exceeds the range of the integer type, then the ''invalid'' floating- point exception is raised and the resulting value is unspecified. Otherwise, the resulting value is determined by 6.3.1.4. Conversion of an integral floating value that does not exceed the range of the integer type raises no floating-point exceptions; whether conversion of a non-integral floating value raises the ''inexact'' floating-point exception is unspecified.360) The public test case: http://www.tybor.com/tflt2int.c shows how bad compilers do for that kind of conversion. --- Fred J. Tydeman Tydeman Consulting tydeman@tybor.com Testing, numerics, programming +1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C") Sample C99+FPCE tests: http://www.tybor.com Savers sleep well, investors eat well, spenders work forever.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web