c ++便携式转换长到双倍 [英] c++ portable conversion of long to double

查看:163
本文介绍了c ++便携式转换长到双倍的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将一个长的代表位精确地转换为双倍,我的解决方案可以移植到不同的体系结构中(可以在编译器中标准化,因为g ++和clang ++ woulf也是很好的)。

I need to accurately convert a long representing bits to a double and my soluton shall be portable to different architectures (being able to be standard across compilers as g++ and clang++ woulf be great too).

我正在为这个问题的答案

double fast_exp(double val)
{
    double result = 0;

    unsigned long temp = (unsigned long)(1512775 * val + 1072632447);
    /* to convert from long bits to double,
   but must check if they have the same size... */
    temp = temp << 32;
    memcpy(&result, &temp, sizeof(temp));

    return result;
}

我正在使用发现的建议此处将long转换为双倍。我正在面对的问题是,虽然我使用clang ++和libc ++在OS X下的[-5,5]中获得了以下结果:

and I'm using the suggestion found here to convert the long into a double. The issue I'm facing is that whereas I got the following results for int values in [-5, 5] under OS X with clang++ and libc++:

0.00675211846828461
0.0183005779981613
0.0504353642463684
0.132078289985657
0.37483024597168
0.971007823944092
2.7694206237793
7.30961990356445
20.3215942382812
54.8094177246094
147.902587890625

我总是在Ubuntu下用clang ++(3.4,同一版本)和libstd ++。编译器甚至告诉我(通过警告),换档操作可能是有问题的,因为long的大小等于或小于移动参数(表示longs和double的大小可能不相同)

I always get 0 under Ubuntu with clang++ (3.4, same version) and libstd++. The compiler there even tells me (through a warning) that the shifting operation can be problematic since the long has size equal or less that the shifting parameter (indicating that longs and doubles have not the same size probably)

我做错了,还是有更好的方法来解决问题,尽可能的更兼容?

Am I doing something wrong and/or is there a better way to solve the problem being as more compatible as possible?

推荐答案

首先,使用长不可移植。使用在stdint.h中找到的固定长度的整数类型。这将减轻需要检查相同的大小,因为你会知道整数的大小。

First off, using "long" isn't portable. Use the fixed length integer types found in stdint.h. This will alleviate the need to check for the same size, since you'll know what size the integer will be.

你得到警告的原因是左移32位intger中的32位是未定义的行为。 移动32位变量32位有什么不好?

The reason you are getting a warning is that left shifting 32 bits on the 32 bit intger is undefined behavior. What's bad about shifting a 32-bit variable 32 bits?

另请参阅这个答案:可以安全地假定sizeof(double)> = sizeof(void *)?应该应该安全地假设双倍是64位,然后你可以使用uint64_t存储原始十六进制。无需检查尺寸,一切便于携带。

Also see this answer: Is it safe to assume sizeof(double) >= sizeof(void*)? It should be safe to assume that a double is 64bits, and then you can use a uint64_t to store the raw hex. No need to check for sizes, and everything is portable.

这篇关于c ++便携式转换长到双倍的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆