Web编程技术营地
研究、演示、创新

Floating Numeric Instructions

撰写时间:2025-01-23

修订时间:2025-01-24

与浮点数有关的指令

nn, mm ::= 32 | 64 sx ::= u | s instr ::= fnn.const fnn | fnn.funop | fnn.fbinop | fnn.frelop | f32.demote_f64 | f64.promote_f32 | fnn.convert_imm_sx | fnn.reinterpret_inn | ... funop ::= abs | neg | sqrt | ceil | floor | trunc | nearest fbinop ::= add | sub | mul | div | min | max | copysign frelop ::= eq | ne | lt | gt | le | ge

设置常数

fnn.const fnn将一个浮点数常数压进Result Stack中。

let watSrc = ` (module (func (export "sum") (result f32) f32.const 0.3 f32.const 0.5 f32.add ) ) `; const { sum } = await WabtUtils.RunWat(watSrc); pc.log(sum());

i64也同样适用于const指令。

let watSrc = ` (module (func (export "sub") (result f64) f64.const 0.7 f64.const 0.25 f64.sub ) ) `; const { sub } = await WabtUtils.RunWat(watSrc); let result = sub(); pc.log(result); pc.log(typeof result);

一元操作指令

一元操作指令是指只有1个操作数的指令,在语法表中使用funop (floating unary operations) 来标识。

abs

abs指令,absolute的缩写,返回操作数的绝对值。

let watSrc = ` (module (func (export "abs") (param f32) (result f32) local.get 0 f32.abs ) ) `; const { abs } = await WabtUtils.RunWat(watSrc); let num = -2.3; pc.log(abs(num));

neg

neg指令,negate的缩写,反转操作数的正负符号。

let watSrc = ` (module (func (export "neg") (param f32) (result f32) local.get 0 f32.neg ) ) `; const { neg } = await WabtUtils.RunWat(watSrc); let num = -2.3; pc.log(neg(num));

sqrt

sqrt指令,square root的缩写,返回操作数的平方根。

let watSrc = ` (module (func (export "sqrt") (param f32) (result f32) local.get 0 f32.sqrt ) ) `; const { sqrt } = await WabtUtils.RunWat(watSrc); let num = 81; pc.log(sqrt(num));

ceil

ceil指令,返回操作数在笛卡尔坐标系Y轴中向上取整的整数。

let watSrc = ` (module (func (export "ceil") (param f32) (result f32) local.get 0 f32.ceil ) ) `; const { ceil } = await WabtUtils.RunWat(watSrc); pc.log(ceil(3.51)); pc.log(ceil(-3.51));

floor

floor指令,返回操作数在笛卡尔坐标系Y轴中向下取整的整数。

let watSrc = ` (module (func (export "floor") (param f32) (result f32) local.get 0 f32.floor ) ) `; const { floor } = await WabtUtils.RunWat(watSrc); pc.log(floor(3.51)); pc.log(floor(-3.51));

trunc

trunc指令,舍弃操作数的小数部分,只保留整数。

let watSrc = ` (module (func (export "trunc") (param f32) (result f32) local.get 0 f32.trunc ) ) `; const { trunc } = await WabtUtils.RunWat(watSrc); pc.log(trunc(3.51)); pc.log(trunc(-3.51));

nearest

nearest指令,四舍五入。

let watSrc = ` (module (func (export "nearest") (param f32) (result f32) local.get 0 f32.nearest ) ) `; const { nearest } = await WabtUtils.RunWat(watSrc); pc.log(nearest(3.51)); pc.log(nearest(-3.21));

二元操作指令

二元操作指令是指有2个操作数的指令,在语法表中使用fbinop (floating binnary operations) 来标识。

add

add指令,将两个操作数相加。

let watSrc = ` (module (func (export "add") (param f32 f32) (result f32) local.get 0 local.get 1 f32.add ) ) `; const { add } = await WabtUtils.RunWat(watSrc); pc.log(add(1.2, 3.4));

sub

sub指令,从第一个操作数减去第二个操作数。

let watSrc = ` (module (func (export "sub") (param f32 f32) (result f32) local.get 0 local.get 1 f32.sub ) ) `; const { sub } = await WabtUtils.RunWat(watSrc); pc.log(sub(1.2, 3.4));

mul

mul指令,将两个操作数相乘。

let watSrc = ` (module (func (export "mul") (param f32 f32) (result f32) local.get 0 local.get 1 f32.mul ) ) `; const { mul } = await WabtUtils.RunWat(watSrc); pc.log(mul(1.5, 3.0));

div

div指令,从第一个操作数除以第二个操作数。

let watSrc = ` (module (func (export "div") (param f32 f32) (result f32) local.get 0 local.get 1 f32.div ) ) `; const { div } = await WabtUtils.RunWat(watSrc); pc.log(div(4.5, 3.0));

min

min指令,从两个操作数中取最小值。

let watSrc = ` (module (func (export "min") (param f32 f32) (result f32) local.get 0 local.get 1 f32.min ) ) `; const { min } = await WabtUtils.RunWat(watSrc); pc.log(min(4.5, 3.2));

max

max指令,从两个操作数中取最小值。

let watSrc = ` (module (func (export "max") (param f32 f32) (result f32) local.get 0 local.get 1 f32.max ) ) `; const { max } = await WabtUtils.RunWat(watSrc); pc.log(max(4.5, 3.2));

copysign

copysign指令,产生一个新数,其数值取自第一个操作数,而符号位取自第二个操作数。

let watSrc = ` (module (func (export "copysign") (param f32 f32) (result f32) local.get 0 local.get 1 f32.copysign ) ) `; const { copysign } = await WabtUtils.RunWat(watSrc); let num1 = 4.5; let num2 = -3.2; let result = copysign(num1, num2); pc.log(result, num1, num2);

比较指令

比较指令消耗2个操作数,返回一个表示真假的数值,1true0false,在语法表中使用frelop (floating relation operations) 来标识。

eq

eq指令,equal的缩写,用于测试2个操作数的数值是否相等。

const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "eq") (param f32 f32) (result i32) local.get 0 local.get 1 f32.eq ) ) `; const { eq } = await WabtUtils.RunWat(watSrc); pc.log(eq(3.5, 3.52));

ne

ne指令,not equal的缩写,用于测试2个操作数的数值是否不等。

const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "ne") (param f32 f32) (result i32) local.get 0 local.get 1 f32.ne ) ) `; const { ne } = await WabtUtils.RunWat(watSrc); pc.log(ne(3.5, 3.52));

lt

lt指令,less than的缩写,用于测试第1个操作数是否小于第2个操作数。

const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "lt") (param f32 f32) (result i32) local.get 0 local.get 1 f32.lt ) ) `; const { lt } = await WabtUtils.RunWat(watSrc); pc.log(lt(1.3, 5.7));

gt

gt指令,greater than的缩写,用于测试第1个操作数是否大于第2个操作数。

const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "gt") (param f32 f32) (result i32) local.get 0 local.get 1 f32.gt ) ) `; const { gt } = await WabtUtils.RunWat(watSrc); pc.log(gt(1.3, 5.7));

le

le指令,less or equal的缩写,用于测试第1个操作数是否小于等于第2个操作数。

const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "le") (param f32 f32) (result i32) local.get 0 local.get 1 f32.le ) ) `; const { le } = await WabtUtils.RunWat(watSrc); pc.log(le(1.3, 5.7));

ge

ge指令,greater or equal的缩写,用于测试第1个操作数是否大于等于第2个操作数。

const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "ge") (param f32 f32) (result i32) local.get 0 local.get 1 f32.ge ) ) `; const { ge } = await WabtUtils.RunWat(watSrc); pc.log(ge(1.3, 5.7));

转换指令

f32.demote_f64

f32.demote_f64指令,将一个f64转换为一个f32

const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "demote") (param f64) (result f32) local.get 0 f32.demote_f64 ) ) `; const { demote } = await WabtUtils.RunWat(watSrc); let num = 25.32; pc.log(num); pc.log(typeof num); pc.log("%s", getBinStr(num, 8)); let result = demote(num); pc.log(result); pc.log(typeof result); pc.log("%s", getBinStr(result, 8));

JavaScript的Number类型的数据,均为IEEE 754-2019 ( IEEE Standard for Floating-Point Arithmetic) 标准下的64位双精度数值,因此JavaScript的Number实参可直接传递给Wasmf64形参。

f64.promote_f32

f64.promote_f32指令,将一个f32转换为一个f64

const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "promote") (param f32) (result f64) local.get 0 f64.promote_f32 ) ) `; const { promote } = await WabtUtils.RunWat(watSrc); let num = 25.32; pc.log(num); pc.log(typeof num); pc.log("%s", getBinStr(num, 8)); let result = promote(num); pc.log(result); pc.log(typeof result); pc.log("%s", getBinStr(result, 8));

convert系列指令

convert系列指令,将一个整数转换为浮点数。需指定是否有符号。

指令名称符号标记含义
f32.convert_i32_ssignedi32转换为一个有符号的f32
f32.convert_i32_uunsignedi32转换为一个无符号的f32
f32.convert_i64_ssignedi64转换为一个有符号的f32
f32.convert_i64_uunsignedi64转换为一个无符号的f32
f64.convert_i32_ssignedi32转换为一个有符号的f64
f64.convert_i32_uunsignedi32转换为一个无符号的f64
f64.convert_i64_ssignedi64转换为一个有符号的f64
f64.convert_i64_uunsignedi64转换为一个无符号的f64
const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "f32_convert_i32_s") (param i32) (result f32) local.get 0 f32.convert_i32_s ) ) `; const { f32_convert_i32_s } = await WabtUtils.RunWat(watSrc); let num = -5; pc.log(f32_convert_i32_s(num));

reinterpret系列指令

reinterpret系列指令,根据一个整数的二进制,重新解释为一个位域相等的浮点数。

指令名称含义
f32.reinterpret_i32i32解释为f32
f64.reinterpret_i64i64解释为f64
const { getBinStr } = await import('/js/esm/BinUtils.js'); let watSrc = ` (module (func (export "reinterpret") (param i32) (result f32) local.get 0 f32.reinterpret_i32 ) ) `; const { reinterpret } = await WabtUtils.RunWat(watSrc); let num = 5; pc.log(num); pc.log("%s", getBinStr(num, 8)); let result = reinterpret(num); pc.log(result); pc.log("%s", getBinStr(result, 8));

参考资源

Main

  1. W3C version (single page)
  2. Doc version (webassembly.org)

Number

  1. Number Types
  2. Numeric Instructions
  3. Numerics
  4. WebAssembly Numeric Instructions (MDN)
  5. Number.MIN_SAFE_INTEGER