数学関数と定数が定義されています。
e
: ネイピア数 (comptime_float
)pi
: 円周率 (comptime_float
)tau
: τ (2 * pi
)nan(T)
: 浮動小数点のNaN (Not a Number) 。T
はf16
/f32
/f64
/f128
のいずれかです。snan(T)
: 浮動小数点のSNaN (Signaling NaN) 。T
はf16
/f32
/f64
/f128
のいずれかです。inf(T)
: 浮動小数点のInfinity。T
はf16
/f32
/f64
/f128
のいずれかです。これらの値はコンパイル時定数です。
maxInt(T)
: 任意整数型の最大値を取得します。minInt(T)
: 任意整数型の最小値を取得します。これらの値はコンパイル時定数です。
floatMantissaBits(comptime T: type) comptime_int
: 浮動小数点型の仮数部が占めるビット数を返します。T
はf16
/f32
/f64
/f128
のいずれかです。floatExponentBits(comptime T: type) comptime_int
: 浮動小数点型の指数部が占めるビット数を返します。T
はf16
/f32
/f64
/f128
のいずれかです。整数型および浮動小数点型でジェネリックに利用できる関数です。
fn min(x: anytype, y: anytype) Min(@TypeOf(x), @TypeOf(y))
2つの数値 (x
/ y
) のうち、最小値を返します。
戻り値型は、以下のように決まります。
examples/ch09-std/math/src/generic.zen:4:29
const math = std.math;
test "math.min" {
ok(math.min( @to(i32, -1), @to(i32, 2) ) == -1 );
// 符号付き/符号なし同士であれば、異なる数値型同士も比較可能
{
var a: u16 = 16;
var b: u32 = 1;
ok(math.min( a, b ) == 1 );
// 符号なし整数同士の場合、よりビット幅の少ない型が戻り値型になる
ok(@TypeOf(math.min( a, b )) == u16 );
}
{
var a: i16 = -16;
var b: i32 = -1;
ok(math.min( a, b ) == -16 );
// 符号付き整数同士の場合、よりビット幅の多い型が戻り値型になる
ok(@TypeOf(math.min( a, b )) == i32 );
}
{
var a: f64 = 12.34;
var b: f32 = 43.21;
ok(math.min( a, b ) == 12.34 );
ok(@TypeOf(math.min( a, b )) == f64 );
}
}
ノート:
math.Min
関数はコンパイル時に実行される関数で、2つの数値型について、符号なし整数型の場合はビット幅が小さい方の型を、それ以外の型の場合はビット幅が大きい方の型を返します。 この関数もpub
なので、アプリケーションから利用することができます。
fn max(x: anytype, y: anytype) @TypeOf(x + y)
2つの数値 (x
/ y
) のうち、最大値を返します。戻り値型は、よりビット幅の大きい型になります。
ノート:
@TypeOf(x + y)
により、より数値の表現幅が広い型に解決されます。
fn pow(comptime T: type, x: T, y: T) T
x
のy
乗を計算します。現在浮動小数点型は、f32
とf64
だけが利用できます。
整数型だけに使えるpowi
もあります。
次の5つの関数は、整数と浮動小数点、両方に使用できる除算/剰余です。ゼロ除算を行おうとした時はerror.DivisionByZero
が、オーバーフロー発生時はerror.Overflow
が返ります。
fn divTrunc(comptime T: type, numerator: T, denominator: T) !T
divTrunc
は0
方向に丸める切り捨て除算を行います。
examples/ch09-std/math/src/generic.zen:31:44
test "divTrunc" {
var result_i32 = try math.divTrunc(i32, 5, 3);
ok(result_i32 == 1);
result_i32 = try math.divTrunc(i32, -5, 3);
ok(result_i32 == -1);
err(error.DivisionByZero, math.divTrunc(i8, -5, 0));
err(error.Overflow, math.divTrunc(i8, -128, -1));
var result_f32 = try math.divTrunc(f32, 5.0, 3.0);
ok(result_f32 == 1.0);
result_f32 = try math.divTrunc(f32, -5.0, 3.0);
ok(result_f32 == -1.0);
}
fn divFloor(comptime T: type, numerator: T, denominator: T) !T
divFloor
は負の無限大へ向かって丸めるフロア除算を行います。
examples/ch09-std/math/src/generic.zen:46:56
test "divFloor" {
var result_i32 = try math.divFloor(i32, 5, 3);
ok(result_i32 == 1);
result_i32 = try math.divFloor(i32, -5, 3);
ok(result_i32 == -2);
var result_f32 = try math.divFloor(f32, 5.0, 3.0);
ok(result_f32 == 1.0);
result_f32 = try math.divFloor(f32, -5.0, 3.0);
ok(result_f32 == -2.0);
}
fn divExact(comptime T: type, numerator: T, denominator: T) !T
divExact
は割り切れる除算を行います。ゼロ除算、オーバーフローに加えて、余りが発生した場合error.UnexpectedRemainder
を返します。
fn mod(comptime T: type, numerator: T, denominator: T) !T
mod
は剰余を計算します。剰余は 0 または正数になります。ゼロ除算に加えて、除数が負数の場合error.NegativeDenominator
を返します。
fn rem(comptime T: type, numerator: T, denominator: T) !T
rem
は剰余を計算します。剰余は被除数と同じ符号になります。ゼロ除算に加えて、除数が負数の場合error.NegativeDenominator
を返します。
mod
とrem
の違いは、次の通りです。また、divFloor
、divTrunc
との関係も記しています。
examples/ch09-std/math/src/generic.zen:58:76
test "mod vs rem" {
const mod = try math.mod(i32, -5, 3);
ok(mod == 1);
const rem = try math.rem(i32, -5, 3);
ok(rem == -2);
const divfloor = try math.divFloor(i32, -5, 3);
ok(divfloor == -2);
const divtrunc = try math.divTrunc(i32, -5, 3);
ok(divtrunc == -1);
// divFloor(x, y) * y + mod(x, y) = x
ok(divfloor * 3 + mod == -5);
// divTrunc(x, y) * y + rem(x, y) = x
ok(divtrunc * 3 + rem == -5);
}
ln(x: anytype) @TypeOf(x)
: x
の自然対数を計算します。log(comptime T: type, base: T, x: T) T
: base
を底とするx
の対数を計算します。mul(comptime T: type, a: T, b: T) !T
: 整数型T
のa * b
を計算します。オーバーフロー発生時は、error.Overflow
が返ります。add(comptime T: type, a: T, b: T) !T
: 整数型T
のa + b
を計算します。オーバーフロー発生時は、error.Overflow
が返ります。sub(comptime T: type, a: T, b: T) !T
: 整数型T
のa - b
を計算します。オーバーフロー発生時は、error.Overflow
が返ります。negate(x: anytype) !@TypeOf(x)
: -x
を計算します。オーバーフロー発生時は、error.Overflow
が返ります。powi(comptime T: type, x: T, y: T) !T
: 整数型T
のx
のy
乗を計算します。オーバーフロー発生時はerror.Overflow
が、アンダーフロー発生時はerror.Underflow
が返ります。rotr(comptime T: type, x: T, r: anytype) T
: 右に回転します。T
は符号なし整数でなければなりません。rotl(comptime T: type, x: T, r: anytype) T
: 左に回転します。T
は符号なし整数でなければなりません。fn negateCast(x: anytype) !Int(true, @TypeOf(x).bit_count)
negateCast
は、-x
を計算します。x
の型が符号なし整数型の場合、戻り値型は符号付き整数型に型変換されます。型変換の結果、オーバーフローが発生した場合、error.Overflow
が返ります。
fn cast(comptime T: type, x: anytype) (error{Overflow}!T)
cast
は整数型同士を型変換します。変換先の型の範囲内で、変換する値が表現できない場合、error.Overflow
が返ります。
isPowerOfTwo(v: anytype) bool
: v
が2の累乗であればtrue
を、そうでなければfalse
を返します。floorPowerOfTwo(comptime T: type, value: T) T
: value
以下の最大の2の累乗を返します。ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T)
: value
以上の最小の2の累乗を返します。T
は符号なし整数型でなければなりません。戻り値がT
で表現できない値の場合、error.Overflow
が返ります。ceilPowerOfTwoPromote(comptime T: type, value: T) T+1ビット幅の整数型
: value
以上の最小の2の累乗を返します。T
は符号なし整数型でなければなりません。戻り値型は、T
+ 1ビットの整数型になるため、オーバーフローは発生しません。examples/ch09-std/math/src/power_of_two.zen:6:28
test "powerOfTwo" {
// 2の累乗であれば`true`、そうでなければ`false`
ok(math.isPowerOfTwo(2) == true);
ok(math.isPowerOfTwo(3) == false);
// 引数以下の最大の2の累乗を返す
ok(math.floorPowerOfTwo(u32, 63) == 32);
ok(math.floorPowerOfTwo(u32, 64) == 64);
ok(math.floorPowerOfTwo(u32, 65) == 64);
// 引数以上の最小の2の累乗を返す
ok(( try math.ceilPowerOfTwo(u32, 63) ) == 64);
ok(( try math.ceilPowerOfTwo(u32, 64) ) == 64);
ok(( try math.ceilPowerOfTwo(u32, 65) ) == 128);
// `256`は`u8`では表現できないため、オーバーフロー
err(error.Overflow, math.ceilPowerOfTwo(u8, 255));
// 戻り値型は、引数型と同じ
ok(@TypeOf(try math.ceilPowerOfTwo(u32, 63)) == u32);
// 戻り値型は、`引数型+1ビットの整数型`になる
ok(math.ceilPowerOfTwoPromote(u8, 255) == 256);
ok(@TypeOf(math.ceilPowerOfTwoPromote(u8, 255)) == u9);
}
isNan(x: anytype) bool
: x
がNaNならtrue
、そうでなければfalse
を返します。isSignalNan(x: anytype) bool
: x
がSignalling NaNならtrue
、そうでなければfalse
を返します。isFinite(x: anytype) bool
: x
が有限値であればtrue
、そうでなければfalse
を返します。isInf(x: anytype) bool
: x
が無限大であればtrue
、そうでなければfalse
を返します。符号は考慮しません。isPositiveInf(x: anytype) bool
: x
が正の無限大であればtrue
、そうでなければfalse
を返します。isNegativeInf(x: anytype) bool
: x
が負の無限大であればtrue
、そうでなければfalse
を返します。isNormal(x: anytype) bool
: x
が正規化数 (仮数部が1) であればtrue
、そうでなければfalse
を返します。signbit(x: anytype) bool
: x
が負数か負の0
であればtrue
、そうでなければfalse
を返します。approxEq(comptime T: type, x: T, y: T, epsilon: T) bool
: x
とy
の差がepsilon
より小さければtrue
、そうでなければfalse
を返します。copysign(comptime T: type, x: T, y: T) T
: x
の指数部と仮数部に、y
の符号ビットを付けた数値を返します。examples/ch09-std/math/src/floats.zen:6:9
test "math.copysign" {
ok(math.copysign(f64, 5.0, -1.0) == -5.0);
ok(math.copysign(f64, -5.0, 1.0) == 5.0);
}
modf(x: anytype) modf_result(@TypeOf(x))
: x
を整数部と小数部に分割します。結果はstruct { fpart: T, ipart: T}
に格納されます。examples/ch09-std/math/src/floats.zen:11:16
test "math.modf" {
const epsilon = 0.000001;
var r = math.modf(@to(f64, 2.545));
ok(math.approxEq(f64, r.ipart, 2.0, epsilon));
ok(math.approxEq(f64, r.fpart, 0.545, epsilon));
}
scalbn(x: anytype, n: i32) @TypeOf(x)
: x * 2^n
を計算します。examples/ch09-std/math/src/floats.zen:18:21
test "math.scalbn" {
// 1.5 * 16
ok(math.scalbn(@to(f64, 1.5), @to(f64, 4)) == 24.0);
}
cbrt(x: anytype) @TypeOf(x)
: x
の立方根を計算します。hypot(comptime T: type, x: T, y: T) T
: 2辺の長さが x
, y
の直角三角形の斜辺の長さを計算します。 (sqrt(x * x + y * y)
)fma(comptime T: type, x: T, y: T, z: T) T
: x
, y
, z
の積和演算 (x * y + z
) を行います。absInt(x: anytype) !@TypeOf(x)
: 整数x
の絶対値を計算します。x
は符号付き整数型の値でなければなりません。x
の絶対値が、x
の型で表現できる範囲内に収まらない場合、error.Overflow
が返ります。absFloat(x: anytype) @TypeOf(x)
: 浮動小数点x
の絶対値を計算します。absCast(x: anytype) (comptime_intかx+1ビットの整数型)
: 整数x
の絶対値を計算します。戻り値型は、comptime_int
か、xの型 + 1ビットの整数型
です。Complex(T) = struct { re: T, im: T }
: T
は浮動小数点型でなければなりません。次のメソッドを実装しています。
new(re: T, im: T) Self
: 新しいインスタンスを生成します。add(self: Self, other: Self) Self
: 2つの複素数値を加算します。sub(self: Self, other: Self) Self
: 2つの複素数値を減算します。mul(self: Self, other: Self) Self
: 2つの複素数値を乗算します。div(self: Self, other: Self) Self
: 2つの複素数値を除算します。conjugate(self: Self) Self
: 複素共役を計算します。reciprocal(self: Self) Self
: 複素数の逆数を計算します。magnitude(self: Self) T
: 複素数の大きさを計算します。complex.zen
モジュールは、他にも、abs
やsin
、exp
、log
、sqrt
などを計算する関数を提供しています。
Int(comptime is_signed: bool, comptime bits: comptime_int) type
: 与えられた符号の有無とビット数を持つ整数型を返します。整数型の最大ビット数は 65535 です。examples/ch09-std/math/src/type.zen:5:17
test "Int type" {
// 符号付き 129ビット整数型
const I129 = math.Int(true, 129);
ok(@typeInfo(I129) == .Int);
ok(@typeInfo(I129).Int.is_signed == true);
ok(@typeInfo(I129).Int.bits == 129);
// 符号なし 7ビット整数型
const U7 = math.Int(false, 7);
ok(@typeInfo(U7) == .Int);
ok(@typeInfo(U7).Int.is_signed == false);
ok(@typeInfo(U7).Int.bits == 7);
}
☰ 人の生きた証は永遠に残るよう ☰
Copyright © 2018-2020 connectFree Corporation. All rights reserved. | 特定商取引法に基づく表示
Zen, the Zen three-circles logo and The Zen Programming Language are trademarks of connectFree corporation in Japan and other countries.