C++11 自动。从浮点数转换为长整数
Posted
技术标签:
【中文标题】C++11 自动。从浮点数转换为长整数【英文标题】:C++11 auto. convert from float to long 【发布时间】:2017-01-02 15:37:14 【问题描述】:是否可以将 foo 从 float 转换为 long(反之亦然)?
auto foo = float(1234567891234.1234);
cout << "foo: " << foo << endl;
foo = long(1234567891234.1234);
cout << "foo: " << foo << endl;
输出总是:
富:1.23457e+12 富:1.23457e+12
【问题讨论】:
这不是问题,但不要使用std::endl
,除非你需要它的额外功能。 '\n'
结束一行。
【参考方案1】:
不是你写的那样。首先,
auto foo = float(1234567891234.1234);
使用自动类型推演规则推断RHS的类型,结果为float
。完成此操作后,foo
的类型为float
,并且一成不变(C++ 为statically typed,与 Python 不同)。下次写的时候
foo = long(1234567891234.1234);
foo 的类型仍然是float
,并没有神奇地变成long
。
如果您想模拟类型的“更改”,您最多可以执行一次强制转换:
cout << "foo (as long): " << static_cast<long>(foo) << endl;
或使用额外的变量
long foo_long = foo; // again you may have a loss of precision
但请注意浮点表示可能导致精度损失。
如果您可以访问 C++17 编译器,则可以使用 std::variant<long, float>
(一种类型安全的联合)在类型之间切换。如果没有,您可以使用普通的旧联合,例如
#include <iostream>
union Foo
float f;
long l;
;
int main()
Foo foo;
foo.f = float(1234567891234.1234); // we set up the float member
std::cout << "foo: " << foo.f << std::endl;
foo.l = long(1234567891234.1234); // we set up the long member
std::cout << "foo: " << foo.l << std::endl;
Live on Coliru
或者,您可以使用类型擦除技术,例如
#include <iostream>
int main()
void *foo; // we will store the object via this pointer
foo = new int42;
std::cout << *(int*)foo << '\n';
operator delete(foo); // don't do delete foo, it is undefined behaviour
foo = new float42.42;
std::cout << *(float*)foo << '\n';
operator delete(foo); // don't do delete foo, it is undefined behaviour
Live on Coliru
上面代码的现代版本可以用std::shared_ptr
之类的方式重写
#include <iostream>
#include <memory>
int main()
std::shared_ptr<void> foonew int42;
std::cout << *(int*)foo.get() << '\n';
foo.reset(new float42.42);
std::cout << *(float*)foo.get() << '\n';
Live on Coliru
std::unique_ptr<void>
无法工作,因为只有 std::shared_ptr
实现了类型擦除。
当然,如果您并不真正关心存储大小等,只需使用 2 个单独的变量即可。
【讨论】:
是否可以这样做: foo = static_castfoo
的类型在程序期间始终为float
。在任何情况下,您都不能更改 C++ 中变量的类型。最接近的方法是使用std::variant<float, long>
(C++17)。
感谢您的帮助。如果你看到这个,我几乎不指望你会做出任何进一步的回应。是否可以在 foo 是浮点数时删除它然后重新初始化它?
@djent 不,仅当您使用示例中的联合时。如果您只是先将其声明为float
,那么无论如何它将保持float
。在 C++ 中,变量的类型是在编译时设置的(也就是说,在程序运行之前),它会保持不变。您可以使用一些称为“type erasure”的技术,在其中声明一个void*
指针,然后继续将其转换为所需的类型,但首先尝试使用最简单、最干净的代码。以上是关于C++11 自动。从浮点数转换为长整数的主要内容,如果未能解决你的问题,请参考以下文章