我在这里做双浮点转换吗
Am I doing double to float conversion here
const double dBLEPTable_8_BLKHAR[4096] = {
0.00000000000000000000000000000000,
-0.00000000239150987901837200000000,
-0.00000000956897738824125100000000,
-0.00000002153888378764179400000000,
-0.00000003830892270073604800000000,
-0.00000005988800189093979000000000,
-0.00000008628624126316708500000000,
-0.00000011751498329992671000000000,
-0.00000015358678995269770000000000,
-0.00000019451544774895524000000000,
-0.00000024031597312124120000000000,
-0.00000029100459975062165000000000
}
如果我将上面的double改为float,那么当我对数组内容执行操作时,我是否正在进行转换cpu周期?或者"转换"是在编译时排序的?
比如说,dBLEPTable_8_BLKHAR[1] + dBLEPTable_8_BLKHAR[2]
,像这样简单的东西?
在一个相关的注意事项上,一个浮点值应该能够存储多少位小数?
这是c++。
任何好的编译器都会在编译时转换初始化程序。然而,你也问
当我对数组内容执行操作时,我是否会招致转换cpu周期?
,这取决于执行操作的代码。如果表达式将数组元素与double
类型的变量组合在一起,则运算将以双倍精度执行,并且数组元素将在进行运算之前升级(转换)。
如果你只是将数组元素与float
类型的变量(包括其他数组元素)组合在一起,那么操作是在浮点上执行的,语言不需要任何升级(但如果你的硬件只实现双精度操作,转换可能仍然可以完成。不过,这样的硬件肯定会使转换非常便宜。)
Ben Voigt的回答解决了您的大部分问题。但你也会问:
在一个相关的注意事项上,一个浮点应该能够存储的小数点后几位
这取决于您试图存储的数字的值。对于大数字,没有小数——事实上,这种格式甚至不能为整数部分提供精确的值。例如:
float x = BIG_NUMBER;
float y = x + 1;
if (x == y)
{
// The code get here if BIG_NUMBER is very high!
}
else
{
// The code get here if BIG_NUMBER is no so high!
}
如果BIG_NUMBER是2^23,则下一个较大的数字将是(2^23+1)。
如果BIG_NUMBER是2^24,则下一个较大的数字将是(2^24+2)。
无法存储值(2^24+1)。
对于非常小的数字(即接近零),你会有很多小数位。
浮点运算要小心使用,因为它们非常不精确。
http://en.wikipedia.org/wiki/Single-precision_floating-point_format
对于小数字,您可以使用下面的程序进行实验。
更改exp变量以设置起点。程序将向您显示范围的步长和前四个有效数字。
int main (int argc, char* argv[])
{
int exp = -27; // <--- !!!!!!!!!!!
// Change this to set starting point for the range
// Starting point will be 2 ^ exp
float f;
unsigned int *d = (unsigned int *)&f; // Brute force to set f in binary format
unsigned int e;
cout.precision(100);
// Calculate step size for this range
e = ((127-23) + exp) << 23;
*d = e;
cout << "Step size = " << fixed << f << endl;
cout << "First 4 numbers in range:" << endl;
// Calculate first four valid numbers in this range
e = (127 + exp) << 23;
*d = e | 0x00000000;
cout << hex << "0x" << *d << " = " << fixed << f << endl;
*d = e | 0x00000001;
cout << hex << "0x" << *d << " = " << fixed << f << endl;
*d = e | 0x00000002;
cout << hex << "0x" << *d << " = " << fixed << f << endl;
*d = e | 0x00000003;
cout << hex << "0x" << *d << " = " << fixed << f << endl;
return 0;
}
对于exp=-27,输出为:
Step size = 0.0000000000000008881784197001252323389053344726562500000000000000000000000000000000000000000000000000
First 4 numbers in range:
0x32000000 = 0.0000000074505805969238281250000000000000000000000000000000000000000000000000000000000000000000000000
0x32000001 = 0.0000000074505814851022478251252323389053344726562500000000000000000000000000000000000000000000000000
0x32000002 = 0.0000000074505823732806675252504646778106689453125000000000000000000000000000000000000000000000000000
0x32000003 = 0.0000000074505832614590872253756970167160034179687500000000000000000000000000000000000000000000000000
const double dBLEPTable_8_BLKHAR[4096] = {
如果您将该行中的double
更改为float
,则会发生以下两种情况之一:
在编译时,编译器会将数字
-0.00000000239150987901837200000000
转换为最能代表它们的float
,然后将数据直接存储到数组中。在运行时,在程序初始化期间(在调用
main()
之前!),编译器生成的运行时将用float
类型的数据填充该数组。
无论哪种方式,一旦到达main()
并编写代码,所有数据都将存储为float
变量。
- 努力将整数转换为链表。不知道我在这里做错了什么
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- File.cpp.o:OpenPose 标志 CMakeFiles/.. 的多重定义/main.cpp.o:首先在这里定
- 为什么thread_local变量在这里从未初始化?
- 为什么我必须在这里使用dynamic_cast
- 奇怪的缩小转换在 g++ 编译器中加倍到浮点警告
- 在这里,当我们比较 if(vc[i]==vc1[i]) 时,它是向量数组. 实际上比较的值是多少,
- C++实用程序::转换在静态链接库中不起作用
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- 为什么 C++20 中的 [[可能]] 属性在这里引发警告?
- 我在这里正确传递参数了吗?
- 复制交换习惯用法-我们可以在这里使用动态强制转换操作吗
- 为什么我在这里收到C++没有已知的转换错误?
- 我在这里做双浮点转换吗
- 为什么整数在这里被转换成八进制
- 在这里做常量转换安全吗
- 我可以在这里使用模板特化或类型强制转换吗?
- 为什么在这里调用转换构造函数
- shared_ptr隐式强制转换在这里失败,在那里成功