From cb56b26900dcb563b008cf132aa3ae180d6a205a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
{#syntax#}@ln(value: var) @TypeOf(value){#endsyntax#}
+ {#header_open|@log#}
+ {#syntax#}@log(value: var) @TypeOf(value){#endsyntax#}
Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available. diff --git a/src/all_types.hpp b/src/all_types.hpp index 53fe034246..dd2b918fc6 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1680,7 +1680,7 @@ enum BuiltinFnId { BuiltinFnIdCos, BuiltinFnIdExp, BuiltinFnIdExp2, - BuiltinFnIdLn, + BuiltinFnIdLog, BuiltinFnIdLog2, BuiltinFnIdLog10, BuiltinFnIdFabs, diff --git a/src/codegen.cpp b/src/codegen.cpp index 5500b4029c..17ae34a1c4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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); diff --git a/src/ir.cpp b/src/ir.cpp index b013553e28..18446ff5b0 100644 --- a/src/ir.cpp +++ b/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; } diff --git a/src/ir.hpp b/src/ir.hpp index a20dc2d232..003bf4897d 100644 --- a/src/ir.hpp +++ b/src/ir.hpp @@ -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); diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 01343e04c4..6c7f216219 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -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, ")"); } diff --git a/test/stage1/behavior/floatop.zig b/test/stage1/behavior/floatop.zig index 04677f59c9..5fe1162502 100644 --- a/test/stage1/behavior/floatop.zig +++ b/test/stage1/behavior/floatop.zig @@ -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); // } //} -- cgit v1.2.3