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&lt;long, float&gt;(一种类型安全的联合)在类型之间切换。如果没有,您可以使用普通的旧联合,例如

#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&lt;void&gt; 无法工作,因为只有 std::shared_ptr 实现了类型擦除。

当然,如果您并不真正关心存储大小等,只需使用 2 个单独的变量即可。

【讨论】:

是否可以这样做: foo = static_cast(foo);并将 foo 更改为 long 类型?有没有可能以某种方式做到这一点? @djent 不,正如我在答案中所说,foo 的类型在程序期间始终为float。在任何情况下,您都不能更改 C++ 中变量的类型。最接近的方法是使用std::variant&lt;float, long&gt; (C++17)。 感谢您的帮助。如果你看到这个,我几乎不指望你会做出任何进一步的回应。是否可以在 foo 是浮点数时删除它然后重新初始化它? @djent 不,仅当您使用示例中的联合时。如果您只是先将其声明为float,那么无论如何它将保持float。在 C++ 中,变量的类型是在编译时设置的(也就是说,在程序运行之前),它会保持不变。您可以使用一些称为“type erasure”的技术,在其中声明一个void* 指针,然后继续将其转换为所需的类型,但首先尝试使用最简单、最干净的代码。

以上是关于C++11 自动。从浮点数转换为长整数的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:无法更新 JSON 列以将值从浮点数转换为整数

将 pandas 数据框列标签从浮点数转换为整数

在 C 中从浮点数转换为无符号字符

从浮点数转换为 QByteArray

在 SQLite 上转换表达式结果,从浮点数到十进制数

使用舍入从浮点数转换为 uint8_t