C++上乌巴消毒剂将负double转换为unsigned long long的问题

bakd9h0s  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(187)

我一直在使用C++,并一直在利用乌巴消毒器将double转换为unsigned long long long。然而,当值为负值时,我遇到了一个问题,这导致了错误消息:“运行时错误:value -2超出了'long long unsigned int'类型的可表示值的范围“
代码如下:

  1. unsigned long long valueULL = 0;
  2. double value = -2;
  3. valueULL = (unsigned long long)value;

我试着用这个石膏代替,它没有帮助:

  1. valueULL = std::make_unsigned_t<unsigned long long>(value);

有没有办法在不遇到此错误的情况下进行强制转换?

f8rj6qna

f8rj6qna1#

看来你指的是clang的-fsanitize=undefined UBSanitizer。sanitizer在这种情况下是正确的,你的代码确实包含未定义的行为:
浮点类型的纯右值可以转换为整数类型的纯右值。转换截断;即丢弃小数部分。截断后的值无法在目标类型中表示,则行为未定义。

  • [conv.fpint] §1
    您可以通过两步强制转换修复未定义的行为:
  1. double value = -2;
  2. auto valueULL = static_cast<unsigned long long>(static_cast<long long>(value));

或者,你可以调用std::llround

  1. auto valueULL = static_cast<unsigned long long>(std::llround(value));

注意:这将产生一个非常大的值,即ULLONG_MAX - 2。如果这是你真正想要的,那么这些解决方案是有意义的。否则,你应该听消毒器,并确保你的double在转换为unsigned类型之前没有变成负数。

相关问题