Skip to content
本页内容

精度转换

二进制精度舍入规则

在了解不同类型之间的精度转换规则之前,需先了解二进制的精度舍入规则。

如下图所示,一个二进制数的尾部若干位可能因目标精度不足而被丢弃,这部分称为待舍入部分;剩余保留的部分称为非舍入部分。根据待舍入部分的值以及所选的精度舍入模式,决定非舍入部分的末位是否需要 +1(进位)

图1 二进制精度舍入规则示意图

二进制精度舍入规则示意图

各精度舍入模式对待舍入部分的判断规则如下表所示:

表1 精度舍入模式

模式描述
CAST_NONE当转换过程存在精度损失时,按CAST_RINT模式处理;当不存在精度损失时,不进行舍入。
CAST_RINT向最近的偶数舍入。
•若待舍入部分的首位为0,则不进位。
•若待舍入部分的首位为1且后续位不全为0,则进位。
•若待舍入部分的首位为1且后续位全为0:当非舍入部分的末位为0,则不进位;当非舍入部分的末位为1,则进位。
CAST_FLOOR向负无穷大方向舍入。
•若符号位(S)为0(正数),则不进位。
•若符号位(S)为1(负数):当待舍入部分全为0,则不进位;否则,进位。
CAST_CEIL向正无穷大方向舍入。
•若符号位(S)为1(负数),则不进位。
•若符号位(S)为0(正数):当待舍入部分全为0,则不进位;否则,进位。
CAST_ROUND四舍五入。若待舍入部分的首位为0,则不进位;否则,进位。
CAST_TRUNC截断模式。直接丢弃待舍入部分。
CAST_ODD向最近的奇数舍入。
•若待舍入部分全为0,则不进位。
•若待舍入部分不全为0:非舍入部分的末位为1,则不进位;当非舍入部分的末位为0,则进位。
CAST_HYBRID随机舍入,目前特指输出结果是hifloat8_t数据类型时,会用到的一种随机舍入。

精度转换规则

本节主要对不同数据类型之间精度转换时的舍入行为进行介绍。不同数据类型的表示方式请参考内置数据类型。当源值超出目标类型的表示范围时溢出,溢出默认按照饱和模式处理。

int4b_t → int16_t

将源值以int16_t格式存入目的操作数中,无精度损失。

示例:输入:1,输出:1。


int4b_t → half

将源值以half格式存入目的操作数中,无精度损失。

示例:输入:1,输出:1.0。


int4b_t → bfloat16_t

将源值以bfloat16_t格式存入目的操作数中,无精度损失。

示例:输入:1,输出:1.0。


int8_t → half

将源值以half格式存入目的操作数中,无精度损失。

示例:输入:-1,输出:-1.0。


int8_t → int16_t

将源值以int16_t格式存入目的操作数中,无精度损失。

示例:输入:,输出:


int8_t → int32_t

将源值以int32_t格式存入目的操作数中,无精度损失。

示例:输入:,输出:


uint8_t → half

将源值以half格式存入目的操作数中,无精度损失。

示例:输入:1,输出:1.0。


uint8_t → uint16_t

将源值以uint16_t格式存入目的操作数中,无精度损失。

示例:输入:,输出:


uint8_t → uint32_t

将源值以uint32_t格式存入目的操作数中,无精度损失。

示例:输入:,输出:


fp4x2_e2m1_t → bfloat16_t

将源值以bfloat16_t格式存入目的操作数中,无精度损失。

示例:输入:2,输出:2。


fp4x2_e1m2_t → bfloat16_t

将源值以bfloat16_t格式存入目的操作数中,无精度损失。

示例:输入:2,输出:2。


hifloat8_t → float

将源值以float格式存入目的操作数中,无精度损失。

示例:输入:2,输出:2。


hifloat8_t → half

将源值以half格式存入目的操作数中,无精度损失。

示例:输入:2,输出:2。


fp8_e5m2_t → float

将源值以float格式存入目的操作数中,无精度损失。

示例:输入:2,输出:2。


fp8_e4m3fn_t → float

将源值以float格式存入目的操作数中,无精度损失。

示例:输入:2,输出:2。


int16_t → int4b_t

将源值以int4b_t格式存入目的操作数中。

示例:输入:,输出:


int16_t → uint8_t

将源值以uint8_t格式存入目的操作数中,高位截断,存在精度损失。负数输入会被视为异常

示例:输入:,输出:


int16_t → half

将源值按照精度舍入模式取到half所能表示的数,以half格式存入目的操作数中。

示例:输入:,写成half的表示形式:,要求

图2 int16_t转half

int16_t转half

由于half只有10bit尾数,因此灰色部分要进行舍入:

  • CAST_RINT模式输入得尾数0000000000,最终结果为:
  • CAST_FLOOR模式输入得尾数0000000000,最终结果为:
  • CAST_CEIL模式舍入得尾数0000000001,最终结果为:
  • CAST_ROUND模式舍入得尾数0000000001,最终结果为:
  • CAST_TRUNC模式舍入得尾数0000000000,最终结果为:

int16_t → uint32_t

将源值以uint32_t格式存入目的操作数中,无精度损失。负数输入会默认转换成0。

示例:输入:,输出:


int16_t → int32_t

将源值以int32_t格式存入目的操作数中,无精度损失。

示例:输入:,输出:


int16_t → float

将源值以float格式存入目的操作数中,无精度损失。

示例:输入:,输出:


uint16_t → uint8_t

将源值以uint8_t格式存入目的操作数中。

示例:输入:,输出:


uint16_t → uint32_t

将源值以uint32_t格式存入目的操作数中,无精度损失。

示例:输入:,输出:


half → int4b_t

将源值按照精度舍入模式取整,以int4b_t格式存入目的操作数中。

示例:输入:,小数部分需要舍入。

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

half → int8_t

将源值按照精度舍入模式取整,以int8_t格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:(溢出处理)。
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:(溢出处理)。
  • CAST_ROUND模式输出:(溢出处理)。
  • CAST_TRUNC模式输出:

half → uint8_t

将源值按照精度舍入模式取整,以uint8_t格式存入目的操作数中。负数输入会被视为异常

示例:输入:

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

half → hifloat8_t

将源值按照精度舍入模式取整,以hifloat8_t格式存入目的操作数中。

示例:输入:


half → int16_t

将源值按照精度舍入模式取整,以int16_t格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

half → bfloat16_t

将源值按照精度舍入模式取整,以bfloat16_t格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

half → int32_t

将源值按照精度舍入模式取整,以int32_t格式存入目的操作数中。

  • 示例:输入:

    • CAST_RINT模式输出:
    • CAST_FLOOR模式输出:
    • CAST_CEIL模式输出:
    • CAST_ROUND模式输出:
    • CAST_TRUNC模式输出:

half → float

将源值以float格式存入目的操作数中,无精度损失。

示例:输入:,输出:


bfloat16_t → fp4x2_e2m1_t

将源值按照精度舍入模式取整,以fp4x2_e2m1_t格式存入目的操作数中。

示例:输入:2.5。

  • CAST_RINT模式输出:2。
  • CAST_FLOOR模式输出:2。
  • CAST_CEIL模式输出:3。
  • CAST_ROUND模式输出:3。
  • CAST_TRUNC模式输出:2。

bfloat16_t → fp4x2_e1m2_t

将源值按照精度舍入模式取整,以fp4x2_e1m2_t格式存入目的操作数中。

示例:输入:2.5。

  • CAST_RINT模式输出:2。
  • CAST_FLOOR模式输出:2。
  • CAST_CEIL模式输出:3。
  • CAST_ROUND模式输出:3。
  • CAST_TRUNC模式输出:2。

bfloat16_t → half

将源值按照精度舍入模式取整,以half格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

bfloat16_t → int32_t

将源值按照精度舍入模式取整,以int32_t格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

bfloat16_t → float

将源值以float格式存入目的操作数中,无精度损失。

示例:输入:,输出:


int32_t → uint8_t

将源值以uint8_t格式存入目的操作数中,高位截断,存在精度损失。负数输入会被视为异常

示例:输入:,输出:


int32_t → uint16_t

将源值以uint16_t格式存入目的操作数中,高位截断,存在精度损失。负数输入会被视为异常

示例:输入:,输出:


int32_t → int16_t

将源值以int16_t格式存入目的操作数中。

示例:输入:,输出:


int32_t → half

当前数据类型组合仅支持配合SetDeqScale接口使用进行数据量化并完成精度转换,精度舍入模式不生效。

输出:


int32_t → float

将源值按照精度舍入模式取到float所能表示的数,以float格式存入目的操作数中。

示例:输入:,写成float的表示形式:,要求

图3 int32_t转float

int32_t转float

由于float只有23bit尾数,因此灰色部分要进行舍入:

  • CAST_RINT模式舍入得尾数00000000000000000000001,最终结果为
  • CAST_FLOOR模式舍入得尾数00000000000000000000000,最终结果为
  • CAST_CEIL模式舍入得尾数00000000000000000000001,最终结果为
  • CAST_ROUND模式舍入得尾数00000000000000000000001,最终结果为
  • CAST_TRUNC模式舍入得尾数00000000000000000000000,最终结果为

int32_t → int64_t

将源值以int64_t格式存入目的操作数中,无精度损失。

示例:输入:,输出:


uint32_t → uint8_t

将源值以uint8_t格式存入目的操作数中。

示例:输入:,输出:


uint32_t → uint16_t

将源值以uint16_t格式存入目的操作数中。

示例:输入:,输出:


uint32_t → int16_t

将源值以int16_t格式存入目的操作数中。

示例:输入:,输出:


float → hifloat8_t

将源值按照精度舍入模式取整,以hifloat8_t格式存入目的操作数中。

示例:输入:


float → fp8_e4m3fn_t

将源值按照精度舍入模式取整,以fp8_e4m3fn_t格式存入目的操作数中。

示例:输入:CAST_RINT模式输出:


float → fp8_e5m2_t

将源值按照精度舍入模式取整,以fp8_e5m2_t格式存入目的操作数中。

示例:输入:CAST_RINT模式输出:


float → int16_t

将源值按照精度舍入模式取整,以int16_t格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:(溢出处理)。
  • CAST_FLOOR模式输出:(溢出处理)。
  • CAST_CEIL模式输出:(溢出处理)。
  • CAST_ROUND模式输出:(溢出处理)。
  • CAST_TRUNC模式输出:(溢出处理)。

float → half

将源值按照精度舍入模式取到half所能表示的数,以half格式存入目的操作数中。

示例:输入:,写成float的表示形式:,因此

图4 float转half

float转half

half的指数位可以表示出,但half只有10bit尾数,因此灰色部分要进行舍入:

  • CAST_RINT模式舍入得尾数0000000000,最终结果为
  • CAST_FLOOR模式舍入得尾数0000000000,最终结果为
  • CAST_CEIL模式舍入得尾数0000000001,最终结果为
  • CAST_ROUND模式舍入得尾数0000000001,最终结果为
  • CAST_TRUNC模式舍入得尾数0000000000,最终结果为
  • CAST_ODD模式舍入得尾数0000000001,最终结果为

float → bfloat16_t

将源值按照精度舍入模式取到bfloat16_t所能表示的数,以bfloat16_t格式存入目的操作数中。

示例:输入:,写成float的表示形式:,因此

图5 float转bfloat16_t

float转bfloat16_t

bfloat16_t的指数位位数和float相同,有,但bfloat16_t只有7bit尾数,因此灰色部分要进行舍入:

  • CAST_RINT模式舍入得尾数0000001,最终结果为
  • CAST_FLOOR模式舍入得尾数0000000,最终结果为
  • CAST_CEIL模式舍入得尾数0000001,最终结果为
  • CAST_ROUND模式舍入得尾数0000001,最终结果为
  • CAST_TRUNC模式舍入得尾数0000000,最终结果为

float → int32_t

将源值按照精度舍入模式取整,以int32_t格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

float → float

将源值按照精度舍入模式取整,仍以float格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

float → int64_t

将源值按照精度舍入模式取整,以int64_t格式存入目的操作数中。

示例:输入:

  • CAST_RINT模式输出:
  • CAST_FLOOR模式输出:
  • CAST_CEIL模式输出:
  • CAST_ROUND模式输出:
  • CAST_TRUNC模式输出:

complex32 → complex64

complex64实部和虚部都是float类型,complex32实部和虚部都是half类型,参考从half到float的精度转换规则。


int64_t → int32_t

将源值以int32_t格式存入目的操作数中。

示例:输入:,输出:


int64_t → float

将源值按照精度舍入模式取到float所能表示的数,以float格式存入目的操作数中。

示例:输入:,写成float的表示形式:,要求

图6 int64_t转float

int64_t转float

由于float只有23bit尾数,因此灰色部分要进行舍入:

  • CAST_RINT模式舍入得尾数00000000000000000000010,最终结果为
  • CAST_FLOOR模式舍入得尾数00000000000000000000001,最终结果为
  • CAST_CEIL模式舍入得尾数00000000000000000000010,最终结果为
  • CAST_ROUND模式舍入得尾数00000000000000000000010,最终结果为
  • CAST_TRUNC模式舍入得尾数00000000000000000000001,最终结果为

int64_t → double

将源值按照精度舍入模式取到double所能表示的数,以double格式存入目的操作数中。

示例:输入:,写成double的表示形式:,要求

图7 int64_t转double示意图

int64_t转double示意图

由于double只有52bit尾数,因此灰色部分要进行舍入:

  • CAST_RINT模式舍入得尾数...010,最终表示的结果为
  • CAST_FLOOR模式舍入得尾数...001,最终表示的结果为
  • CAST_CEIL模式舍入得尾数...010,最终表示的结果为
  • CAST_ROUND模式舍入得尾数...010,最终表示的结果为
  • CAST_TRUNC模式舍入得尾数...001,最终表示的结果为

double → float

将源值按照精度舍入模式取到float所能表示的数,以float格式存入目的操作数中。

示例:输入:,写成float的表示形式:,要求

图8 double转float示意图

double转float示意图

由于float只有8bit指数,指数部分需要转换,只有23bit尾数,因此灰色部分要进行舍入:

  • CAST_RINT模式舍入得尾数00000000000000000000010,,最终表示的结果为
  • CAST_FLOOR模式舍入得尾数00000000000000000000001,,最终表示的结果为
  • CAST_CEIL模式舍入得尾数00000000000000000000010,,最终表示的结果为
  • CAST_ROUND模式舍入得尾数00000000000000000000010,,最终表示的结果为
  • CAST_TRUNC模式舍入得尾数00000000000000000000001,,最终表示的结果为

double → bfloat16_t

将源值按照精度舍入模式取到bfloat16_t所能表示的数,以bfloat16_t格式存入目的操作数中。

示例:输入:,写成bfloat16_t的表示形式:,要求

图9 double转bfloat16_t示意图

double转bfloat16_t示意图

由于bfloat16_t只有8bit指数,指数部分需要转换,只有7bit尾数,因此灰色部分要进行舍入:

  • CAST_RINT模式舍入得尾数0000010,,最终表示的结果为
  • CAST_FLOOR模式舍入得尾数0000001,,最终表示的结果为
  • CAST_CEIL模式舍入得尾数0000010,,最终表示的结果为
  • CAST_ROUND模式舍入得尾数0000010,,最终表示的结果为
  • CAST_TRUNC模式舍入得尾数0000001,,最终表示的结果为

double → int32_t

将源值按照精度舍入模式取整,以int32_t格式存入目的操作数中。

示例:输入:-1.5,CAST_TRUNC模式输出:-1。


double → int64_t

将源值按照精度舍入模式取整,以int64_t格式存入目的操作数中。

示例:输入:-1.5,CAST_TRUNC模式输出:-1。


complex64 → complex64

complex64实部和虚部都是float类型,参考float与float之间的精度转换规则。


complex64 → complex32

complex64实部和虚部都是float类型,complex32实部和虚部都是half类型,参考从float到half的精度转换规则。


免责声明:本站内容由 asc-devkit 仓 master 分支自动编译生成,属于持续开发版本,可能存在缺陷,仅供预览与参考。如需稳定及商用资料,请查阅官方 昇腾社区