SkyWalker
SkyWalker

Reputation: 14317

int64_t conversion to 'long double' issue

The following code produces the shown output and I'm confused ... I'm using Intel compiler version 2013 beta update 2 /opt/intel/composer_xe_2013.0.030/bin/intel64/icpc:

// all good
int64_t fops_count1 = 719508467815;
long double fops_count2 = boost::static_cast<long double>(fops_count1);
printf("%" PRIu64 "\n", fops_count1); // OK outputs 719508467815
printf("%Le\n", fops_count2);         // OK outputs 7.195085e+11

// bad! why this?
int64_t fops_count1 = 18446743496931269238;
long double fops_count2 = boost::static_cast<long double>(fops_count1);
printf("%" PRIu64 "\n", fops_count1); // OK outputs 18446743496931269238
printf("%Le\n", fops_count2);         // FAIL outputs -5.767783e+11 <<<<<<<<<<<<<<<<< WHY?

Upvotes: 1

Views: 1222

Answers (2)

Puppy
Puppy

Reputation: 147028

int64_t fops_count1 = 18446743496931269238;

This is signed overflow, which is UB. The maximum value of an int64_t is on the order of 2^63, which is definitely less than this value. Seems like your processor implements wraparound, giving the negative value you see.

Upvotes: 1

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145429

Ignoring the boost::static_cast, which I don't understand, a 64-bit signed integer can't represent the number you showed, but

18446743496931269238 - 264 = -576778282378

I.e. this is the value you get when a two's complement 64-bit signed integer wraps around.

Now what's that boost::static_cast?

Upvotes: 4

Related Questions