mirror of
https://github.com/ziglang/zig.git
synced 2025-02-10 22:50:18 +00:00
fix comptime vector float ops and add test coverage
also rename `@ln` to `@log` to match libc convention.
This commit is contained in:
parent
cb56b26900
commit
213ff939f1
@ -8130,8 +8130,8 @@ test "vector @splat" {
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@ln#}
|
||||
<pre>{#syntax#}@ln(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
{#header_open|@log#}
|
||||
<pre>{#syntax#}@log(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction
|
||||
when available.
|
||||
|
@ -1680,7 +1680,7 @@ enum BuiltinFnId {
|
||||
BuiltinFnIdCos,
|
||||
BuiltinFnIdExp,
|
||||
BuiltinFnIdExp2,
|
||||
BuiltinFnIdLn,
|
||||
BuiltinFnIdLog,
|
||||
BuiltinFnIdLog2,
|
||||
BuiltinFnIdLog10,
|
||||
BuiltinFnIdFabs,
|
||||
|
@ -764,7 +764,7 @@ static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn
|
||||
name = "fma";
|
||||
num_args = 3;
|
||||
} else if (fn_id == ZigLLVMFnIdFloatOp) {
|
||||
name = float_op_to_name(op, true);
|
||||
name = float_op_to_name(op);
|
||||
num_args = 1;
|
||||
} else {
|
||||
zig_unreachable();
|
||||
@ -8205,7 +8205,7 @@ static void define_builtin_fns(CodeGen *g) {
|
||||
create_builtin_fn(g, BuiltinFnIdCos, "cos", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdExp, "exp", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdExp2, "exp2", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdLn, "ln", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdLog, "log", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdLog2, "log2", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdLog10, "log10", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdFabs, "fabs", 1);
|
||||
|
85
src/ir.cpp
85
src/ir.cpp
@ -3125,9 +3125,7 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode
|
||||
//TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign,
|
||||
// lround, llround, lrint, llrint
|
||||
// So far this is only non-complicated type functions.
|
||||
const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
|
||||
const bool b = llvm_name;
|
||||
|
||||
const char *float_op_to_name(BuiltinFnId op) {
|
||||
switch (op) {
|
||||
case BuiltinFnIdSqrt:
|
||||
return "sqrt";
|
||||
@ -3139,8 +3137,8 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
|
||||
return "exp";
|
||||
case BuiltinFnIdExp2:
|
||||
return "exp2";
|
||||
case BuiltinFnIdLn:
|
||||
return b ? "log" : "ln";
|
||||
case BuiltinFnIdLog:
|
||||
return "log";
|
||||
case BuiltinFnIdLog10:
|
||||
return "log10";
|
||||
case BuiltinFnIdLog2:
|
||||
@ -3154,7 +3152,7 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
|
||||
case BuiltinFnIdTrunc:
|
||||
return "trunc";
|
||||
case BuiltinFnIdNearbyInt:
|
||||
return b ? "nearbyint" : "nearbyInt";
|
||||
return "nearbyint";
|
||||
case BuiltinFnIdRound:
|
||||
return "round";
|
||||
default:
|
||||
@ -5497,7 +5495,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
|
||||
case BuiltinFnIdCos:
|
||||
case BuiltinFnIdExp:
|
||||
case BuiltinFnIdExp2:
|
||||
case BuiltinFnIdLn:
|
||||
case BuiltinFnIdLog:
|
||||
case BuiltinFnIdLog2:
|
||||
case BuiltinFnIdLog10:
|
||||
case BuiltinFnIdFabs:
|
||||
@ -27626,7 +27624,7 @@ static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, I
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, BuiltinFnId fop, ZigType *float_type,
|
||||
static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, BuiltinFnId fop, ZigType *float_type,
|
||||
ZigValue *op, ZigValue *out_val)
|
||||
{
|
||||
assert(ira && source_instr && float_type && out_val && op);
|
||||
@ -27653,24 +27651,49 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
|
||||
out_val->data.x_f16 = f16_sqrt(op->data.x_f16);
|
||||
break;
|
||||
case BuiltinFnIdSin:
|
||||
out_val->data.x_f16 = zig_double_to_f16(sin(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdCos:
|
||||
out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdExp:
|
||||
out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdExp2:
|
||||
case BuiltinFnIdLn:
|
||||
out_val->data.x_f16 = zig_double_to_f16(exp2(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdLog:
|
||||
out_val->data.x_f16 = zig_double_to_f16(log(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdLog10:
|
||||
out_val->data.x_f16 = zig_double_to_f16(log10(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdLog2:
|
||||
out_val->data.x_f16 = zig_double_to_f16(log2(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdFabs:
|
||||
out_val->data.x_f16 = zig_double_to_f16(fabs(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdFloor:
|
||||
out_val->data.x_f16 = zig_double_to_f16(floor(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdCeil:
|
||||
out_val->data.x_f16 = zig_double_to_f16(ceil(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdTrunc:
|
||||
out_val->data.x_f16 = zig_double_to_f16(trunc(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdNearbyInt:
|
||||
out_val->data.x_f16 = zig_double_to_f16(nearbyint(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
case BuiltinFnIdRound:
|
||||
zig_panic("unimplemented f16 builtin");
|
||||
out_val->data.x_f16 = zig_double_to_f16(round(zig_f16_to_double(op->data.x_f16)));
|
||||
break;
|
||||
default:
|
||||
zig_unreachable();
|
||||
};
|
||||
break;
|
||||
};
|
||||
}
|
||||
case 32: {
|
||||
switch (fop) {
|
||||
case BuiltinFnIdSqrt:
|
||||
@ -27688,7 +27711,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
|
||||
case BuiltinFnIdExp2:
|
||||
out_val->data.x_f32 = exp2f(op->data.x_f32);
|
||||
break;
|
||||
case BuiltinFnIdLn:
|
||||
case BuiltinFnIdLog:
|
||||
out_val->data.x_f32 = logf(op->data.x_f32);
|
||||
break;
|
||||
case BuiltinFnIdLog10:
|
||||
@ -27719,7 +27742,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
|
||||
zig_unreachable();
|
||||
};
|
||||
break;
|
||||
};
|
||||
}
|
||||
case 64: {
|
||||
switch (fop) {
|
||||
case BuiltinFnIdSqrt:
|
||||
@ -27737,7 +27760,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
|
||||
case BuiltinFnIdExp2:
|
||||
out_val->data.x_f64 = exp2(op->data.x_f64);
|
||||
break;
|
||||
case BuiltinFnIdLn:
|
||||
case BuiltinFnIdLog:
|
||||
out_val->data.x_f64 = log(op->data.x_f64);
|
||||
break;
|
||||
case BuiltinFnIdLog10:
|
||||
@ -27768,7 +27791,11 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
|
||||
zig_unreachable();
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
case 80:
|
||||
return ir_add_error(ira, source_instr,
|
||||
buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
|
||||
float_op_to_name(fop), buf_ptr(&float_type->name)));
|
||||
case 128: {
|
||||
float128_t *out, *in;
|
||||
if (float_type->id == ZigTypeIdComptimeFloat) {
|
||||
@ -27787,7 +27814,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
|
||||
case BuiltinFnIdCos:
|
||||
case BuiltinFnIdExp:
|
||||
case BuiltinFnIdExp2:
|
||||
case BuiltinFnIdLn:
|
||||
case BuiltinFnIdLog:
|
||||
case BuiltinFnIdLog10:
|
||||
case BuiltinFnIdLog2:
|
||||
case BuiltinFnIdFabs:
|
||||
@ -27795,15 +27822,19 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
|
||||
case BuiltinFnIdCeil:
|
||||
case BuiltinFnIdTrunc:
|
||||
case BuiltinFnIdRound:
|
||||
zig_panic("unimplemented f128 builtin");
|
||||
return ir_add_error(ira, source_instr,
|
||||
buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
|
||||
float_op_to_name(fop), buf_ptr(&float_type->name)));
|
||||
default:
|
||||
zig_unreachable();
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
default:
|
||||
zig_unreachable();
|
||||
}
|
||||
out_val->special = ConstValSpecialStatic;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) {
|
||||
@ -27838,17 +27869,27 @@ static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstruct
|
||||
expand_undef_array(ira->codegen, out_val);
|
||||
size_t len = operand_type->data.vector.len;
|
||||
for (size_t i = 0; i < len; i += 1) {
|
||||
ZigValue *float_operand_op1 = &operand_val->data.x_array.data.s_none.elements[i];
|
||||
ZigValue *elem_operand = &operand_val->data.x_array.data.s_none.elements[i];
|
||||
ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i];
|
||||
ir_assert(float_operand_op1->type == scalar_type, &instruction->base);
|
||||
ir_assert(elem_operand->type == scalar_type, &instruction->base);
|
||||
ir_assert(float_out_val->type == scalar_type, &instruction->base);
|
||||
ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type, operand_val, float_out_val);
|
||||
ErrorMsg *msg = ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type,
|
||||
elem_operand, float_out_val);
|
||||
if (msg != nullptr) {
|
||||
add_error_note(ira->codegen, msg, instruction->base.source_node,
|
||||
buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
float_out_val->type = scalar_type;
|
||||
}
|
||||
out_val->type = operand_type;
|
||||
out_val->special = ConstValSpecialStatic;
|
||||
} else {
|
||||
ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type, operand_val, out_val);
|
||||
if (ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type,
|
||||
operand_val, out_val) != nullptr)
|
||||
{
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ bool ir_has_side_effects(IrInstruction *instruction);
|
||||
struct IrAnalyze;
|
||||
ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
|
||||
AstNode *source_node);
|
||||
const char *float_op_to_name(BuiltinFnId op, bool llvm_name);
|
||||
const char *float_op_to_name(BuiltinFnId op);
|
||||
|
||||
// for debugging purposes
|
||||
void dbg_ir_break(const char *src_file, uint32_t line);
|
||||
|
@ -2005,7 +2005,7 @@ static void ir_print_add_implicit_return_type(IrPrint *irp, IrInstructionAddImpl
|
||||
}
|
||||
|
||||
static void ir_print_float_op(IrPrint *irp, IrInstructionFloatOp *instruction) {
|
||||
fprintf(irp->f, "@%s(", float_op_to_name(instruction->fn_id, false));
|
||||
fprintf(irp->f, "@%s(", float_op_to_name(instruction->fn_id));
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ const math = std.math;
|
||||
const pi = std.math.pi;
|
||||
const e = std.math.e;
|
||||
|
||||
const epsilon = 0.000001;
|
||||
|
||||
test "@sqrt" {
|
||||
comptime testSqrt();
|
||||
testSqrt();
|
||||
@ -17,6 +19,8 @@ fn testSqrt() void {
|
||||
{
|
||||
var a: f32 = 9;
|
||||
expect(@sqrt(a) == 3);
|
||||
var b: f32 = 1.1;
|
||||
expect(math.approxEq(f32, @sqrt(b), 1.0488088481701516, epsilon));
|
||||
}
|
||||
{
|
||||
var a: f64 = 25;
|
||||
@ -31,12 +35,18 @@ fn testSqrt() void {
|
||||
// var a: f128 = 49;
|
||||
// expect(@sqrt(a) == 7);
|
||||
//}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
||||
var result = @sqrt(v);
|
||||
expect(math.approxEq(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @sqrt(@as(f32, 3.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @sqrt(@as(f32, 4.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "more @sqrt f16 tests" {
|
||||
// TODO these are not all passing at comptime
|
||||
const epsilon = 0.000001;
|
||||
|
||||
expect(@sqrt(@as(f16, 0.0)) == 0.0);
|
||||
expect(math.approxEq(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));
|
||||
expect(math.approxEq(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon));
|
||||
@ -61,8 +71,12 @@ test "@sin" {
|
||||
}
|
||||
|
||||
fn testSin() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 0;
|
||||
expect(@sin(a) == 0);
|
||||
}
|
||||
{
|
||||
var a: f32 = 0;
|
||||
expect(@sin(a) == 0);
|
||||
@ -71,6 +85,14 @@ fn testSin() void {
|
||||
var a: f64 = 0;
|
||||
expect(@sin(a) == 0);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
||||
var result = @sin(v);
|
||||
expect(math.approxEq(f32, @sin(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @sin(@as(f32, 2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @sin(@as(f32, 3.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @sin(@as(f32, 4.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@cos" {
|
||||
@ -79,8 +101,12 @@ test "@cos" {
|
||||
}
|
||||
|
||||
fn testCos() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 0;
|
||||
expect(@cos(a) == 1);
|
||||
}
|
||||
{
|
||||
var a: f32 = 0;
|
||||
expect(@cos(a) == 1);
|
||||
@ -89,6 +115,14 @@ fn testCos() void {
|
||||
var a: f64 = 0;
|
||||
expect(@cos(a) == 1);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
|
||||
var result = @cos(v);
|
||||
expect(math.approxEq(f32, @cos(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @cos(@as(f32, 2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @cos(@as(f32, 3.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @cos(@as(f32, 4.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@exp" {
|
||||
@ -97,8 +131,12 @@ test "@exp" {
|
||||
}
|
||||
|
||||
fn testExp() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 0;
|
||||
expect(@exp(a) == 1);
|
||||
}
|
||||
{
|
||||
var a: f32 = 0;
|
||||
expect(@exp(a) == 1);
|
||||
@ -107,6 +145,14 @@ fn testExp() void {
|
||||
var a: f64 = 0;
|
||||
expect(@exp(a) == 1);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var result = @exp(v);
|
||||
expect(math.approxEq(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @exp(@as(f32, 2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @exp(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @exp(@as(f32, 0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@exp2" {
|
||||
@ -115,8 +161,12 @@ test "@exp2" {
|
||||
}
|
||||
|
||||
fn testExp2() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 2;
|
||||
expect(@exp2(a) == 4);
|
||||
}
|
||||
{
|
||||
var a: f32 = 2;
|
||||
expect(@exp2(a) == 4);
|
||||
@ -125,25 +175,45 @@ fn testExp2() void {
|
||||
var a: f64 = 2;
|
||||
expect(@exp2(a) == 4);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var result = @exp2(v);
|
||||
expect(math.approxEq(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @exp2(@as(f32, 2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @exp2(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @exp2(@as(f32, 0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@ln" {
|
||||
test "@log" {
|
||||
// Old musl (and glibc?), and our current math.ln implementation do not return 1
|
||||
// so also accept those values.
|
||||
comptime testLn();
|
||||
testLn();
|
||||
comptime testLog();
|
||||
testLog();
|
||||
}
|
||||
|
||||
fn testLn() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
fn testLog() void {
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = e;
|
||||
expect(math.approxEq(f16, @log(a), 1, epsilon));
|
||||
}
|
||||
{
|
||||
var a: f32 = e;
|
||||
expect(@ln(a) == 1 or @ln(a) == @bitCast(f32, @as(u32, 0x3f7fffff)));
|
||||
expect(@log(a) == 1 or @log(a) == @bitCast(f32, @as(u32, 0x3f7fffff)));
|
||||
}
|
||||
{
|
||||
var a: f64 = e;
|
||||
expect(@ln(a) == 1 or @ln(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
|
||||
expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var result = @log(v);
|
||||
expect(math.approxEq(f32, @log(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @log(@as(f32, 2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @log(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @log(@as(f32, 0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,8 +223,12 @@ test "@log2" {
|
||||
}
|
||||
|
||||
fn testLog2() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 4;
|
||||
expect(@log2(a) == 2);
|
||||
}
|
||||
{
|
||||
var a: f32 = 4;
|
||||
expect(@log2(a) == 2);
|
||||
@ -163,6 +237,14 @@ fn testLog2() void {
|
||||
var a: f64 = 4;
|
||||
expect(@log2(a) == 2);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var result = @log2(v);
|
||||
expect(math.approxEq(f32, @log2(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @log2(@as(f32, 2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @log2(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @log2(@as(f32, 0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@log10" {
|
||||
@ -171,8 +253,12 @@ test "@log10" {
|
||||
}
|
||||
|
||||
fn testLog10() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 100;
|
||||
expect(@log10(a) == 2);
|
||||
}
|
||||
{
|
||||
var a: f32 = 100;
|
||||
expect(@log10(a) == 2);
|
||||
@ -181,6 +267,14 @@ fn testLog10() void {
|
||||
var a: f64 = 1000;
|
||||
expect(@log10(a) == 3);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
|
||||
var result = @log10(v);
|
||||
expect(math.approxEq(f32, @log10(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @log10(@as(f32, 2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @log10(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @log10(@as(f32, 0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@fabs" {
|
||||
@ -189,8 +283,14 @@ test "@fabs" {
|
||||
}
|
||||
|
||||
fn testFabs() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = -2.5;
|
||||
var b: f16 = 2.5;
|
||||
expect(@fabs(a) == 2.5);
|
||||
expect(@fabs(b) == 2.5);
|
||||
}
|
||||
{
|
||||
var a: f32 = -2.5;
|
||||
var b: f32 = 2.5;
|
||||
@ -203,6 +303,14 @@ fn testFabs() void {
|
||||
expect(@fabs(a) == 2.5);
|
||||
expect(@fabs(b) == 2.5);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
||||
var result = @fabs(v);
|
||||
expect(math.approxEq(f32, @fabs(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @fabs(@as(f32, -2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @fabs(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @fabs(@as(f32, -0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@floor" {
|
||||
@ -211,8 +319,12 @@ test "@floor" {
|
||||
}
|
||||
|
||||
fn testFloor() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 2.1;
|
||||
expect(@floor(a) == 2);
|
||||
}
|
||||
{
|
||||
var a: f32 = 2.1;
|
||||
expect(@floor(a) == 2);
|
||||
@ -221,6 +333,14 @@ fn testFloor() void {
|
||||
var a: f64 = 3.5;
|
||||
expect(@floor(a) == 3);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
||||
var result = @floor(v);
|
||||
expect(math.approxEq(f32, @floor(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @floor(@as(f32, -2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @floor(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @floor(@as(f32, -0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@ceil" {
|
||||
@ -229,8 +349,12 @@ test "@ceil" {
|
||||
}
|
||||
|
||||
fn testCeil() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 2.1;
|
||||
expect(@ceil(a) == 3);
|
||||
}
|
||||
{
|
||||
var a: f32 = 2.1;
|
||||
expect(@ceil(a) == 3);
|
||||
@ -239,6 +363,14 @@ fn testCeil() void {
|
||||
var a: f64 = 3.5;
|
||||
expect(@ceil(a) == 4);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
||||
var result = @ceil(v);
|
||||
expect(math.approxEq(f32, @ceil(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @ceil(@as(f32, -2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @ceil(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @ceil(@as(f32, -0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
test "@trunc" {
|
||||
@ -247,8 +379,12 @@ test "@trunc" {
|
||||
}
|
||||
|
||||
fn testTrunc() void {
|
||||
// TODO test f16, f128, and c_longdouble
|
||||
// TODO test f128, and c_longdouble
|
||||
// https://github.com/ziglang/zig/issues/4026
|
||||
{
|
||||
var a: f16 = 2.1;
|
||||
expect(@trunc(a) == 2);
|
||||
}
|
||||
{
|
||||
var a: f32 = 2.1;
|
||||
expect(@trunc(a) == 2);
|
||||
@ -257,10 +393,18 @@ fn testTrunc() void {
|
||||
var a: f64 = -3.5;
|
||||
expect(@trunc(a) == -3);
|
||||
}
|
||||
{
|
||||
var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
|
||||
var result = @trunc(v);
|
||||
expect(math.approxEq(f32, @trunc(@as(f32, 1.1)), result[0], epsilon));
|
||||
expect(math.approxEq(f32, @trunc(@as(f32, -2.2)), result[1], epsilon));
|
||||
expect(math.approxEq(f32, @trunc(@as(f32, 0.3)), result[2], epsilon));
|
||||
expect(math.approxEq(f32, @trunc(@as(f32, -0.4)), result[3], epsilon));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)
|
||||
//test "@nearbyInt" {
|
||||
//test "@nearbyint" {
|
||||
// comptime testNearbyInt();
|
||||
// testNearbyInt();
|
||||
//}
|
||||
@ -270,10 +414,10 @@ fn testTrunc() void {
|
||||
// // https://github.com/ziglang/zig/issues/4026
|
||||
// {
|
||||
// var a: f32 = 2.1;
|
||||
// expect(@nearbyInt(a) == 2);
|
||||
// expect(@nearbyint(a) == 2);
|
||||
// }
|
||||
// {
|
||||
// var a: f64 = -3.75;
|
||||
// expect(@nearbyInt(a) == -4);
|
||||
// expect(@nearbyint(a) == -4);
|
||||
// }
|
||||
//}
|
||||
|
Loading…
Reference in New Issue
Block a user