Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   C/C++ pitfalls related to 64-bits (unsigned long & double) (http://www.velocityreviews.com/forums/t868275-c-c-pitfalls-related-to-64-bits-unsigned-long-and-double.html)

Alex Vinokur 02-13-2012 12:41 PM

C/C++ pitfalls related to 64-bits (unsigned long & double)
 
Hi,

unsigned long a = -1;
double b = a;
unsigned long c = b;

Model 32-bits: a == c
Model 64-bits: a != c


It is not a compiler bug for 64-bits.

Is it a design bug of C/C++ languge for 64-bits?

Alex

Goran 02-13-2012 12:54 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
On Feb 13, 1:41*pm, Alex Vinokur <alex.vino...@gmail.com> wrote:
> Hi,
>
> unsigned long a = -1;
> double b = a;
> unsigned long c = b;
>
> Model 32-bits: * a == c
> Model 64-bits: * a != c
>
> It is not a compiler bug for 64-bits.
>
> Is it a design bug of C/C++ languge for 64-bits?


No. Your code snippet will produce "c" that equals "a" on both 32- and
64-bit systems.

If you think there is, post an example that shows the problem, e.g.:

#include <iostream>
int main()
{
unsigned long a = -1;
double b = a;
unsigned long c = b;
if (a != c)
{
std::cout << "error!";
}
}

Goran.

Alex Vinokur 02-13-2012 12:59 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
On Feb 13, 2:49*pm, Leigh Johnston <le...@i42.co.uk> wrote:
> On 13/02/2012 12:41, Alex Vinokur wrote:
>
> > Hi,

>
> > unsigned long a = -1;
> > double b = a;
> > unsigned long c = b;

>
> > Model 32-bits: * a == c
> > Model 64-bits: * a != c

>
> > It is not a compiler bug for 64-bits.

>
> > Is it a design bug of C/C++ languge for 64-bits?

>
> No.
>
> a == c for both "32-bits" and "64-bits" on my compiler (VC9).
>
> /Leigh


aCC: HP C/aC++ B3910B A.06.25.01 [May 16 2010]
For 64-bits:
a = 0xffffffffffffffff
c = 0x8000000000000000

Intel(R) C++ Intel(R) 64 Compiler XE for applications running on
Intel(R) 64, Version 12.0.4.191 Build 20110427
For 64-bits:
a = 0xffffffffffffffff
c = 0






Alex Vinokur 02-13-2012 01:00 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
On Feb 13, 2:54*pm, Goran <goran.pu...@gmail.com> wrote:
> On Feb 13, 1:41*pm, Alex Vinokur <alex.vino...@gmail.com> wrote:
>
> > Hi,

>
> > unsigned long a = -1;
> > double b = a;
> > unsigned long c = b;

>
> > Model 32-bits: * a == c
> > Model 64-bits: * a != c

>
> > It is not a compiler bug for 64-bits.

>
> > Is it a design bug of C/C++ languge for 64-bits?

>
> No. Your code snippet will produce "c" that equals "a" on both 32- and
> 64-bit systems.
>
> If you think there is, post an example that shows the problem, e.g.:
>
> #include <iostream>
> int main()
> {
> *unsigned long a = -1;
> *double b = a;
> *unsigned long c = b;
> *if (a != c)
> *{
> * std::cout << "error!";
> *}
>
> }
>
> Goran.


#include <iostream>
#include <cassert>

typedef unsigned char uchar;

#define SHOW_HEX(x) std::cerr << #x << " = " << std::hex <<
std::showbase << x << std::dec << std::endl
#define SHOW_DOUBLE(x) std::cerr << #x << " = " << x << std::endl
#define SHOW_CHAR(x) std::cerr << #x << " = " << std::hex <<
std::showbase << std::size_t(uchar(x)) << std::dec << std::endl

int main()
{
// -------------------------------------
std::cout << "Model: " << sizeof(void*) * CHAR_BIT << "-bits"<<
std::endl;
// -------------------------------------

// std::size_t a = std::size_t(-1);
// double b = a;
std::size_t a = std::numeric_limits<std::size_t>::max();
double b = a;
std::size_t c = b;
char* pa = reinterpret_cast<char*>(&a);
char* pb = reinterpret_cast<char*>(&b);
char* pc = reinterpret_cast<char*>(&c);

SHOW_HEX(a);
SHOW_DOUBLE(b);
SHOW_HEX(c);

std::cerr << std::endl;
for (std::size_t i = 0; i < (sizeof(std::size_t)/sizeof(char)); i++)
{
SHOW_CHAR(pa[i]);
}
std::cerr << std::endl;
for (std::size_t i = 0; i < (sizeof(double)/sizeof(char)); i++)
{
SHOW_CHAR(pb[i]);
}
std::cerr << std::endl;
for (std::size_t i = 0; i < (sizeof(std::size_t)/sizeof(char)); i++)
{
SHOW_CHAR(pc[i]);
}

assert (a == c);

return 0;
}

Eric Sosman 02-13-2012 01:14 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
On 2/13/2012 7:41 AM, Alex Vinokur wrote:
> Hi,
>
> unsigned long a = -1;
> double b = a;
> unsigned long c = b;
>
> Model 32-bits: a == c
> Model 64-bits: a != c
>
>
> It is not a compiler bug for 64-bits.
>
> Is it a design bug of C/C++ languge for 64-bits?


Whether the language design is faulty seems a matter of opinion.
However, part of the "spirit of C" is to stay fairly close to the
hardware. Since hardware that offers 64 bits of precision in the
floating-point format used for `double', some loss of precision in
`b = a' must be expected.

The language *could* have been defined to raise an exception
whenever a floating-point operation delivers an inexact result, but
that would have meant raising such exceptions for a large fraction
of all F-P calculations, perhaps many times in a single expression.
Or the language could have left the inexact conversion entirely
undefined, in which case there'd be no reason to expect `a == c'
(or even that the execution would get that far). The behavior
actually chosen (conversion yields one of the two representable
neighbors) seems fairly benign, not something I'd call a bug. But,
as I say, that's a matter of opinion.

(The language *could* have been defined to deliver exact F-P
results for all calculations, widening the representation at need.
That's the approach used on the Starship Enterprise, where Kirk
crippled the computer by asking it to calculate pi ...)

--
Eric Sosman
esosman@ieee-dot-org.invalid

Ben Bacarisse 02-13-2012 01:16 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
Alex Vinokur <alex.vinokur@gmail.com> writes:

Talking from the C perspective here...

> unsigned long a = -1;
> double b = a;
> unsigned long c = b;
>
> Model 32-bits: a == c
> Model 64-bits: a != c
>
> It is not a compiler bug for 64-bits.


Quite. Both outcomes are permitted.

> Is it a design bug of C/C++ languge for 64-bits?


No.

Your use of "64-bits" is a little confusing. Not all 64-bit systems
have 64 bit unsigned longs which is, I think, what you are talking
about.

On systems with 64-bit longs and standard 56-bit mantissa doubles, you
can not represent ULONG_MAX (the value of 'a' in the above code) exactly
in a double. C mandates that you get one of the two nearest
representable values, but it wont be exact. When the conversion goes
the other way the result can be undefined (if the floating point values
was rounded up to a value larger that ULONG_MAX), but, even if the
double has a value in the range of unsigned long, it will not longer
equal ULONG_MAX.

I said "no" to it being an error in the design of the language because
solving it would impose the kind of burden on implementations that C
rejects. C is designed to use native machine types wherever possible.

--
Ben.

Eric Sosman 02-13-2012 01:17 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
On 2/13/2012 8:14 AM, Eric Sosman wrote:
> [...] Since hardware that offers 64 bits of precision in the
> floating-point format used for `double', some loss of precision in
> `b = a' must be expected.


Oh, drat. There was supposed to be an "is fairly rare" just
before the comma ...

--
Eric Sosman
esosman@ieee-dot-org.invalid

Ben Bacarisse 02-13-2012 01:27 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
Goran <goran.pusic@gmail.com> writes:

> On Feb 13, 1:41*pm, Alex Vinokur <alex.vino...@gmail.com> wrote:
>> Hi,
>>
>> unsigned long a = -1;
>> double b = a;
>> unsigned long c = b;
>>
>> Model 32-bits: * a == c
>> Model 64-bits: * a != c
>>
>> It is not a compiler bug for 64-bits.
>>
>> Is it a design bug of C/C++ languge for 64-bits?

>
> No. Your code snippet will produce "c" that equals "a" on both 32- and
> 64-bit systems.


Not always. His (and your) use of "64-bit systems" hides that fact that
they are not all the same:

$ cat t.c
#include <stdio.h>

int main(void)
{
unsigned long a = -1;
puts(a == (unsigned long)(double)a ? "same" : "different");
}
$ gcc -o t -std=c99 -pedantic t.c
$ ./t
different

(g++ will do the same, here).

<snip>
--
Ben.

Noob 02-13-2012 02:22 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
Alex Vinokur wrote:

> Hi,
>
> unsigned long a = -1;
> double b = a;
> unsigned long c = b;
>
> Model 32-bits: a == c
> Model 64-bits: a != c
>
>
> It is not a compiler bug for 64-bits.
>
> Is it a design bug of C/C++ languge for 64-bits?


Nicely done. You've hit all the right nails.

Remaining conspicuously vague, conflating C and C++ while cross-posting
to both groups, claiming a defect in the language, conjuring the ever
so misunderstood floating-point format, ...

You would make Kenny so proud!

If you're bored, you could read Goldberg's paper (all of it!)
http://docs.oracle.com/cd/E19957-01/..._goldberg.html

Goran 02-13-2012 03:14 PM

Re: C/C++ pitfalls related to 64-bits (unsigned long & double)
 
On Feb 13, 1:54*pm, Goran <goran.pu...@gmail.com> wrote:
> On Feb 13, 1:41*pm, Alex Vinokur <alex.vino...@gmail.com> wrote:
>
> > Hi,

>
> > unsigned long a = -1;
> > double b = a;
> > unsigned long c = b;

>
> > Model 32-bits: * a == c
> > Model 64-bits: * a != c

>
> > It is not a compiler bug for 64-bits.

>
> > Is it a design bug of C/C++ languge for 64-bits?

>
> No. Your code snippet will produce "c" that equals "a" on both 32- and
> 64-bit systems.


Here I stand ashamed. I overlook the "unsigned" part. :-(

It's what Noob says, first and foremost. max of size_t is likely
2^64-1. That's more digits than number of significant digits "double"
can carry.

Goran.


All times are GMT. The time now is 10:45 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.