簡體   English   中英

為什么從浮點到 integer 的轉換會截斷?

[英]Why does a cast from floating point to integer truncate?

在 C 和 C++ 中,我們都知道將浮點值轉換為 integer 會執行截斷 這意味着,對於static_cast和 C 風格的演員表,對零的修復。

static_assert(static_cast<int>(2.9) == 2);
static_assert((int)-3.7 == -3);

要將浮點數轉換為 integer,有 4 個選項,每個選項都由<cmath>中的標准 function 實現:

  1. round
  2. floor
  3. ceil
  4. trunc

根據我自己的經驗,我從最常用到最不常用的選項排序(這有點主觀)。

向零截斷意味着從 -0.999... 到 0.999... 的所有值都轉換為 0。因此,在 0 附近存在數學異常,這使得截斷很少有用。 我的印象是,幾乎每次程序員直接將浮點數轉換為 integer 時,他實際上都想要floor ,但可以承受trunc行為,因為該值應該始終為正。

我的問題是:select 第四個選項截斷的動機是什么? 我敢打賭這主要是歷史性的,但是當最初開發 C 時,肯定有一些充分的理由將 select 截斷而不是更有用的舍入或地板。

當您想要對值的模數進行下限時使用它,而與符號無關。 發生這種情況的原因有多種,每個應用程序都是特定的。 你可能會在物理、金融、工程等領域擁有它。

在 x86_64 上, trunc(float)映射到glibc 上的roundss指令

ENTRY(__truncf_sse41)
        roundss        $11, %xmm0, %xmm0
        ret
END(__truncf_sse41)

上面的常量 $11,它是實際指令的立即操作數,並確定舍入特性。 該特定指令包含您提到的選項(請參閱Intel Intrinsics Guide ):

__m128 _mm_round_ss (__m128 a, __m128 b, int rounding)
Synopsis
__m128 _mm_round_ss (__m128 a, __m128 b, int rounding)
#include <smmintrin.h>
Instruction: roundss xmm, xmm, imm8
CPUID Flags: SSE4.1
Description
Round the lower single-precision (32-bit) floating-point element in b using the rounding parameter, store the result as a single-precision floating-point element in the lower element of dst, and copy the upper 3 packed elements from a to the upper elements of dst.
Rounding is done according to the rounding[3:0] parameter, which can be one of:
    (_MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC) // round to nearest, and suppress exceptions
    (_MM_FROUND_TO_NEG_INF |_MM_FROUND_NO_EXC)     // round down, and suppress exceptions
    (_MM_FROUND_TO_POS_INF |_MM_FROUND_NO_EXC)     // round up, and suppress exceptions
    (_MM_FROUND_TO_ZERO |_MM_FROUND_NO_EXC)        // truncate, and suppress exceptions
    _MM_FROUND_CUR_DIRECTION // use MXCSR.RC; see _MM_SET_ROUNDING_MODE

所以這絕不是語言的選擇,而是用戶的需求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM