authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-02 14:01:48-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-02 14:01:48-05:00
log213ff939f18f147b5d9dd164d52ebdd660dab7b4
treebc647d607254e1668b40199cb9c483900359d4fe
parentcb56b26900dcb563b008cf132aa3ae180d6a205a
signaturelock-open Commit is signed but in an unrecognized format.

fix comptime vector float ops and add test coverage

also rename `@ln` to `@log` to match libc convention.

7 files changed, 236 insertions(+), 51 deletions(-)

doc/langref.html.in+2-2
......@@ -8130,8 +8130,8 @@ test "vector @splat" {
81308130 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
81318131 </p>
81328132 {#header_close#}
8133 {#header_open|@ln#}
8134 <pre>{#syntax#}@ln(value: var) @TypeOf(value){#endsyntax#}</pre>
8133 {#header_open|@log#}
8134 <pre>{#syntax#}@log(value: var) @TypeOf(value){#endsyntax#}</pre>
81358135 <p>
81368136 Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction
81378137 when available.
src/all_types.hpp+1-1
......@@ -1680,7 +1680,7 @@ enum BuiltinFnId {
16801680 BuiltinFnIdCos,
16811681 BuiltinFnIdExp,
16821682 BuiltinFnIdExp2,
1683 BuiltinFnIdLn,
1683 BuiltinFnIdLog,
16841684 BuiltinFnIdLog2,
16851685 BuiltinFnIdLog10,
16861686 BuiltinFnIdFabs,
src/codegen.cpp+2-2
......@@ -764,7 +764,7 @@ static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn
764764 name = "fma";
765765 num_args = 3;
766766 } else if (fn_id == ZigLLVMFnIdFloatOp) {
767 name = float_op_to_name(op, true);
767 name = float_op_to_name(op);
768768 num_args = 1;
769769 } else {
770770 zig_unreachable();
......@@ -8205,7 +8205,7 @@ static void define_builtin_fns(CodeGen *g) {
82058205 create_builtin_fn(g, BuiltinFnIdCos, "cos", 1);
82068206 create_builtin_fn(g, BuiltinFnIdExp, "exp", 1);
82078207 create_builtin_fn(g, BuiltinFnIdExp2, "exp2", 1);
8208 create_builtin_fn(g, BuiltinFnIdLn, "ln", 1);
8208 create_builtin_fn(g, BuiltinFnIdLog, "log", 1);
82098209 create_builtin_fn(g, BuiltinFnIdLog2, "log2", 1);
82108210 create_builtin_fn(g, BuiltinFnIdLog10, "log10", 1);
82118211 create_builtin_fn(g, BuiltinFnIdFabs, "fabs", 1);
src/ir.cpp+63-22
......@@ -3125,9 +3125,7 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode
31253125//TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign,
31263126// lround, llround, lrint, llrint
31273127// So far this is only non-complicated type functions.
3128const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
3129 const bool b = llvm_name;
3130
3128const char *float_op_to_name(BuiltinFnId op) {
31313129 switch (op) {
31323130 case BuiltinFnIdSqrt:
31333131 return "sqrt";
......@@ -3139,8 +3137,8 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
31393137 return "exp";
31403138 case BuiltinFnIdExp2:
31413139 return "exp2";
3142 case BuiltinFnIdLn:
3143 return b ? "log" : "ln";
3140 case BuiltinFnIdLog:
3141 return "log";
31443142 case BuiltinFnIdLog10:
31453143 return "log10";
31463144 case BuiltinFnIdLog2:
......@@ -3154,7 +3152,7 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
31543152 case BuiltinFnIdTrunc:
31553153 return "trunc";
31563154 case BuiltinFnIdNearbyInt:
3157 return b ? "nearbyint" : "nearbyInt";
3155 return "nearbyint";
31583156 case BuiltinFnIdRound:
31593157 return "round";
31603158 default:
......@@ -5497,7 +5495,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
54975495 case BuiltinFnIdCos:
54985496 case BuiltinFnIdExp:
54995497 case BuiltinFnIdExp2:
5500 case BuiltinFnIdLn:
5498 case BuiltinFnIdLog:
55015499 case BuiltinFnIdLog2:
55025500 case BuiltinFnIdLog10:
55035501 case BuiltinFnIdFabs:
......@@ -27626,7 +27624,7 @@ static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, I
2762627624 return result;
2762727625}
2762827626
27629static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, BuiltinFnId fop, ZigType *float_type,
27627static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, BuiltinFnId fop, ZigType *float_type,
2763027628 ZigValue *op, ZigValue *out_val)
2763127629{
2763227630 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
2765327651 out_val->data.x_f16 = f16_sqrt(op->data.x_f16);
2765427652 break;
2765527653 case BuiltinFnIdSin:
27654 out_val->data.x_f16 = zig_double_to_f16(sin(zig_f16_to_double(op->data.x_f16)));
27655 break;
2765627656 case BuiltinFnIdCos:
27657 out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16)));
27658 break;
2765727659 case BuiltinFnIdExp:
27660 out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16)));
27661 break;
2765827662 case BuiltinFnIdExp2:
27659 case BuiltinFnIdLn:
27663 out_val->data.x_f16 = zig_double_to_f16(exp2(zig_f16_to_double(op->data.x_f16)));
27664 break;
27665 case BuiltinFnIdLog:
27666 out_val->data.x_f16 = zig_double_to_f16(log(zig_f16_to_double(op->data.x_f16)));
27667 break;
2766027668 case BuiltinFnIdLog10:
27669 out_val->data.x_f16 = zig_double_to_f16(log10(zig_f16_to_double(op->data.x_f16)));
27670 break;
2766127671 case BuiltinFnIdLog2:
27672 out_val->data.x_f16 = zig_double_to_f16(log2(zig_f16_to_double(op->data.x_f16)));
27673 break;
2766227674 case BuiltinFnIdFabs:
27675 out_val->data.x_f16 = zig_double_to_f16(fabs(zig_f16_to_double(op->data.x_f16)));
27676 break;
2766327677 case BuiltinFnIdFloor:
27678 out_val->data.x_f16 = zig_double_to_f16(floor(zig_f16_to_double(op->data.x_f16)));
27679 break;
2766427680 case BuiltinFnIdCeil:
27681 out_val->data.x_f16 = zig_double_to_f16(ceil(zig_f16_to_double(op->data.x_f16)));
27682 break;
2766527683 case BuiltinFnIdTrunc:
27684 out_val->data.x_f16 = zig_double_to_f16(trunc(zig_f16_to_double(op->data.x_f16)));
27685 break;
2766627686 case BuiltinFnIdNearbyInt:
27687 out_val->data.x_f16 = zig_double_to_f16(nearbyint(zig_f16_to_double(op->data.x_f16)));
27688 break;
2766727689 case BuiltinFnIdRound:
27668 zig_panic("unimplemented f16 builtin");
27690 out_val->data.x_f16 = zig_double_to_f16(round(zig_f16_to_double(op->data.x_f16)));
27691 break;
2766927692 default:
2767027693 zig_unreachable();
2767127694 };
2767227695 break;
27673 };
27696 }
2767427697 case 32: {
2767527698 switch (fop) {
2767627699 case BuiltinFnIdSqrt:
......@@ -27688,7 +27711,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
2768827711 case BuiltinFnIdExp2:
2768927712 out_val->data.x_f32 = exp2f(op->data.x_f32);
2769027713 break;
27691 case BuiltinFnIdLn:
27714 case BuiltinFnIdLog:
2769227715 out_val->data.x_f32 = logf(op->data.x_f32);
2769327716 break;
2769427717 case BuiltinFnIdLog10:
......@@ -27719,7 +27742,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
2771927742 zig_unreachable();
2772027743 };
2772127744 break;
27722 };
27745 }
2772327746 case 64: {
2772427747 switch (fop) {
2772527748 case BuiltinFnIdSqrt:
......@@ -27737,7 +27760,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
2773727760 case BuiltinFnIdExp2:
2773827761 out_val->data.x_f64 = exp2(op->data.x_f64);
2773927762 break;
27740 case BuiltinFnIdLn:
27763 case BuiltinFnIdLog:
2774127764 out_val->data.x_f64 = log(op->data.x_f64);
2774227765 break;
2774327766 case BuiltinFnIdLog10:
......@@ -27768,7 +27791,11 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
2776827791 zig_unreachable();
2776927792 }
2777027793 break;
27771 };
27794 }
27795 case 80:
27796 return ir_add_error(ira, source_instr,
27797 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
27798 float_op_to_name(fop), buf_ptr(&float_type->name)));
2777227799 case 128: {
2777327800 float128_t *out, *in;
2777427801 if (float_type->id == ZigTypeIdComptimeFloat) {
......@@ -27787,7 +27814,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
2778727814 case BuiltinFnIdCos:
2778827815 case BuiltinFnIdExp:
2778927816 case BuiltinFnIdExp2:
27790 case BuiltinFnIdLn:
27817 case BuiltinFnIdLog:
2779127818 case BuiltinFnIdLog10:
2779227819 case BuiltinFnIdLog2:
2779327820 case BuiltinFnIdFabs:
......@@ -27795,15 +27822,19 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
2779527822 case BuiltinFnIdCeil:
2779627823 case BuiltinFnIdTrunc:
2779727824 case BuiltinFnIdRound:
27798 zig_panic("unimplemented f128 builtin");
27825 return ir_add_error(ira, source_instr,
27826 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
27827 float_op_to_name(fop), buf_ptr(&float_type->name)));
2779927828 default:
2780027829 zig_unreachable();
2780127830 }
2780227831 break;
27803 };
27832 }
2780427833 default:
2780527834 zig_unreachable();
2780627835 }
27836 out_val->special = ConstValSpecialStatic;
27837 return nullptr;
2780727838}
2780827839
2780927840static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) {
......@@ -27838,17 +27869,27 @@ static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstruct
2783827869 expand_undef_array(ira->codegen, out_val);
2783927870 size_t len = operand_type->data.vector.len;
2784027871 for (size_t i = 0; i < len; i += 1) {
27841 ZigValue *float_operand_op1 = &operand_val->data.x_array.data.s_none.elements[i];
27872 ZigValue *elem_operand = &operand_val->data.x_array.data.s_none.elements[i];
2784227873 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i];
27843 ir_assert(float_operand_op1->type == scalar_type, &instruction->base);
27874 ir_assert(elem_operand->type == scalar_type, &instruction->base);
2784427875 ir_assert(float_out_val->type == scalar_type, &instruction->base);
27845 ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type, operand_val, float_out_val);
27876 ErrorMsg *msg = ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type,
27877 elem_operand, float_out_val);
27878 if (msg != nullptr) {
27879 add_error_note(ira->codegen, msg, instruction->base.source_node,
27880 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i));
27881 return ira->codegen->invalid_instruction;
27882 }
2784627883 float_out_val->type = scalar_type;
2784727884 }
2784827885 out_val->type = operand_type;
2784927886 out_val->special = ConstValSpecialStatic;
2785027887 } else {
27851 ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type, operand_val, out_val);
27888 if (ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type,
27889 operand_val, out_val) != nullptr)
27890 {
27891 return ira->codegen->invalid_instruction;
27892 }
2785227893 }
2785327894 return result;
2785427895 }
src/ir.hpp+1-1
......@@ -33,7 +33,7 @@ bool ir_has_side_effects(IrInstruction *instruction);
3333struct IrAnalyze;
3434ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
3535 AstNode *source_node);
36const char *float_op_to_name(BuiltinFnId op, bool llvm_name);
36const char *float_op_to_name(BuiltinFnId op);
3737
3838// for debugging purposes
3939void dbg_ir_break(const char *src_file, uint32_t line);
src/ir_print.cpp+1-1
......@@ -2005,7 +2005,7 @@ static void ir_print_add_implicit_return_type(IrPrint *irp, IrInstructionAddImpl
20052005}
20062006
20072007static void ir_print_float_op(IrPrint *irp, IrInstructionFloatOp *instruction) {
2008 fprintf(irp->f, "@%s(", float_op_to_name(instruction->fn_id, false));
2008 fprintf(irp->f, "@%s(", float_op_to_name(instruction->fn_id));
20092009 ir_print_other_instruction(irp, instruction->operand);
20102010 fprintf(irp->f, ")");
20112011}
test/stage1/behavior/floatop.zig+166-22
......@@ -4,6 +4,8 @@ const math = std.math;
44const pi = std.math.pi;
55const e = std.math.e;
66
7const epsilon = 0.000001;
8
79test "@sqrt" {
810 comptime testSqrt();
911 testSqrt();
......@@ -17,6 +19,8 @@ fn testSqrt() void {
1719 {
1820 var a: f32 = 9;
1921 expect(@sqrt(a) == 3);
22 var b: f32 = 1.1;
23 expect(math.approxEq(f32, @sqrt(b), 1.0488088481701516, epsilon));
2024 }
2125 {
2226 var a: f64 = 25;
......@@ -31,12 +35,18 @@ fn testSqrt() void {
3135 // var a: f128 = 49;
3236 // expect(@sqrt(a) == 7);
3337 //}
38 {
39 var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
40 var result = @sqrt(v);
41 expect(math.approxEq(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon));
42 expect(math.approxEq(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon));
43 expect(math.approxEq(f32, @sqrt(@as(f32, 3.3)), result[2], epsilon));
44 expect(math.approxEq(f32, @sqrt(@as(f32, 4.4)), result[3], epsilon));
45 }
3446}
3547
3648test "more @sqrt f16 tests" {
3749 // TODO these are not all passing at comptime
38 const epsilon = 0.000001;
39
4050 expect(@sqrt(@as(f16, 0.0)) == 0.0);
4151 expect(math.approxEq(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));
4252 expect(math.approxEq(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon));
......@@ -61,8 +71,12 @@ test "@sin" {
6171}
6272
6373fn testSin() void {
64 // TODO test f16, f128, and c_longdouble
74 // TODO test f128, and c_longdouble
6575 // https://github.com/ziglang/zig/issues/4026
76 {
77 var a: f16 = 0;
78 expect(@sin(a) == 0);
79 }
6680 {
6781 var a: f32 = 0;
6882 expect(@sin(a) == 0);
......@@ -71,6 +85,14 @@ fn testSin() void {
7185 var a: f64 = 0;
7286 expect(@sin(a) == 0);
7387 }
88 {
89 var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
90 var result = @sin(v);
91 expect(math.approxEq(f32, @sin(@as(f32, 1.1)), result[0], epsilon));
92 expect(math.approxEq(f32, @sin(@as(f32, 2.2)), result[1], epsilon));
93 expect(math.approxEq(f32, @sin(@as(f32, 3.3)), result[2], epsilon));
94 expect(math.approxEq(f32, @sin(@as(f32, 4.4)), result[3], epsilon));
95 }
7496}
7597
7698test "@cos" {
......@@ -79,8 +101,12 @@ test "@cos" {
79101}
80102
81103fn testCos() void {
82 // TODO test f16, f128, and c_longdouble
104 // TODO test f128, and c_longdouble
83105 // https://github.com/ziglang/zig/issues/4026
106 {
107 var a: f16 = 0;
108 expect(@cos(a) == 1);
109 }
84110 {
85111 var a: f32 = 0;
86112 expect(@cos(a) == 1);
......@@ -89,6 +115,14 @@ fn testCos() void {
89115 var a: f64 = 0;
90116 expect(@cos(a) == 1);
91117 }
118 {
119 var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 3.3, 4.4};
120 var result = @cos(v);
121 expect(math.approxEq(f32, @cos(@as(f32, 1.1)), result[0], epsilon));
122 expect(math.approxEq(f32, @cos(@as(f32, 2.2)), result[1], epsilon));
123 expect(math.approxEq(f32, @cos(@as(f32, 3.3)), result[2], epsilon));
124 expect(math.approxEq(f32, @cos(@as(f32, 4.4)), result[3], epsilon));
125 }
92126}
93127
94128test "@exp" {
......@@ -97,8 +131,12 @@ test "@exp" {
97131}
98132
99133fn testExp() void {
100 // TODO test f16, f128, and c_longdouble
134 // TODO test f128, and c_longdouble
101135 // https://github.com/ziglang/zig/issues/4026
136 {
137 var a: f16 = 0;
138 expect(@exp(a) == 1);
139 }
102140 {
103141 var a: f32 = 0;
104142 expect(@exp(a) == 1);
......@@ -107,6 +145,14 @@ fn testExp() void {
107145 var a: f64 = 0;
108146 expect(@exp(a) == 1);
109147 }
148 {
149 var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
150 var result = @exp(v);
151 expect(math.approxEq(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
152 expect(math.approxEq(f32, @exp(@as(f32, 2.2)), result[1], epsilon));
153 expect(math.approxEq(f32, @exp(@as(f32, 0.3)), result[2], epsilon));
154 expect(math.approxEq(f32, @exp(@as(f32, 0.4)), result[3], epsilon));
155 }
110156}
111157
112158test "@exp2" {
......@@ -115,8 +161,12 @@ test "@exp2" {
115161}
116162
117163fn testExp2() void {
118 // TODO test f16, f128, and c_longdouble
164 // TODO test f128, and c_longdouble
119165 // https://github.com/ziglang/zig/issues/4026
166 {
167 var a: f16 = 2;
168 expect(@exp2(a) == 4);
169 }
120170 {
121171 var a: f32 = 2;
122172 expect(@exp2(a) == 4);
......@@ -125,25 +175,45 @@ fn testExp2() void {
125175 var a: f64 = 2;
126176 expect(@exp2(a) == 4);
127177 }
178 {
179 var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
180 var result = @exp2(v);
181 expect(math.approxEq(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
182 expect(math.approxEq(f32, @exp2(@as(f32, 2.2)), result[1], epsilon));
183 expect(math.approxEq(f32, @exp2(@as(f32, 0.3)), result[2], epsilon));
184 expect(math.approxEq(f32, @exp2(@as(f32, 0.4)), result[3], epsilon));
185 }
128186}
129187
130test "@ln" {
188test "@log" {
131189 // Old musl (and glibc?), and our current math.ln implementation do not return 1
132190 // so also accept those values.
133 comptime testLn();
134 testLn();
191 comptime testLog();
192 testLog();
135193}
136194
137fn testLn() void {
138 // TODO test f16, f128, and c_longdouble
195fn testLog() void {
196 // TODO test f128, and c_longdouble
139197 // https://github.com/ziglang/zig/issues/4026
198 {
199 var a: f16 = e;
200 expect(math.approxEq(f16, @log(a), 1, epsilon));
201 }
140202 {
141203 var a: f32 = e;
142 expect(@ln(a) == 1 or @ln(a) == @bitCast(f32, @as(u32, 0x3f7fffff)));
204 expect(@log(a) == 1 or @log(a) == @bitCast(f32, @as(u32, 0x3f7fffff)));
143205 }
144206 {
145207 var a: f64 = e;
146 expect(@ln(a) == 1 or @ln(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
208 expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
209 }
210 {
211 var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
212 var result = @log(v);
213 expect(math.approxEq(f32, @log(@as(f32, 1.1)), result[0], epsilon));
214 expect(math.approxEq(f32, @log(@as(f32, 2.2)), result[1], epsilon));
215 expect(math.approxEq(f32, @log(@as(f32, 0.3)), result[2], epsilon));
216 expect(math.approxEq(f32, @log(@as(f32, 0.4)), result[3], epsilon));
147217 }
148218}
149219
......@@ -153,8 +223,12 @@ test "@log2" {
153223}
154224
155225fn testLog2() void {
156 // TODO test f16, f128, and c_longdouble
226 // TODO test f128, and c_longdouble
157227 // https://github.com/ziglang/zig/issues/4026
228 {
229 var a: f16 = 4;
230 expect(@log2(a) == 2);
231 }
158232 {
159233 var a: f32 = 4;
160234 expect(@log2(a) == 2);
......@@ -163,6 +237,14 @@ fn testLog2() void {
163237 var a: f64 = 4;
164238 expect(@log2(a) == 2);
165239 }
240 {
241 var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
242 var result = @log2(v);
243 expect(math.approxEq(f32, @log2(@as(f32, 1.1)), result[0], epsilon));
244 expect(math.approxEq(f32, @log2(@as(f32, 2.2)), result[1], epsilon));
245 expect(math.approxEq(f32, @log2(@as(f32, 0.3)), result[2], epsilon));
246 expect(math.approxEq(f32, @log2(@as(f32, 0.4)), result[3], epsilon));
247 }
166248}
167249
168250test "@log10" {
......@@ -171,8 +253,12 @@ test "@log10" {
171253}
172254
173255fn testLog10() void {
174 // TODO test f16, f128, and c_longdouble
256 // TODO test f128, and c_longdouble
175257 // https://github.com/ziglang/zig/issues/4026
258 {
259 var a: f16 = 100;
260 expect(@log10(a) == 2);
261 }
176262 {
177263 var a: f32 = 100;
178264 expect(@log10(a) == 2);
......@@ -181,6 +267,14 @@ fn testLog10() void {
181267 var a: f64 = 1000;
182268 expect(@log10(a) == 3);
183269 }
270 {
271 var v: @Vector(4, f32) = [_]f32{1.1, 2.2, 0.3, 0.4};
272 var result = @log10(v);
273 expect(math.approxEq(f32, @log10(@as(f32, 1.1)), result[0], epsilon));
274 expect(math.approxEq(f32, @log10(@as(f32, 2.2)), result[1], epsilon));
275 expect(math.approxEq(f32, @log10(@as(f32, 0.3)), result[2], epsilon));
276 expect(math.approxEq(f32, @log10(@as(f32, 0.4)), result[3], epsilon));
277 }
184278}
185279
186280test "@fabs" {
......@@ -189,8 +283,14 @@ test "@fabs" {
189283}
190284
191285fn testFabs() void {
192 // TODO test f16, f128, and c_longdouble
286 // TODO test f128, and c_longdouble
193287 // https://github.com/ziglang/zig/issues/4026
288 {
289 var a: f16 = -2.5;
290 var b: f16 = 2.5;
291 expect(@fabs(a) == 2.5);
292 expect(@fabs(b) == 2.5);
293 }
194294 {
195295 var a: f32 = -2.5;
196296 var b: f32 = 2.5;
......@@ -203,6 +303,14 @@ fn testFabs() void {
203303 expect(@fabs(a) == 2.5);
204304 expect(@fabs(b) == 2.5);
205305 }
306 {
307 var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
308 var result = @fabs(v);
309 expect(math.approxEq(f32, @fabs(@as(f32, 1.1)), result[0], epsilon));
310 expect(math.approxEq(f32, @fabs(@as(f32, -2.2)), result[1], epsilon));
311 expect(math.approxEq(f32, @fabs(@as(f32, 0.3)), result[2], epsilon));
312 expect(math.approxEq(f32, @fabs(@as(f32, -0.4)), result[3], epsilon));
313 }
206314}
207315
208316test "@floor" {
......@@ -211,8 +319,12 @@ test "@floor" {
211319}
212320
213321fn testFloor() void {
214 // TODO test f16, f128, and c_longdouble
322 // TODO test f128, and c_longdouble
215323 // https://github.com/ziglang/zig/issues/4026
324 {
325 var a: f16 = 2.1;
326 expect(@floor(a) == 2);
327 }
216328 {
217329 var a: f32 = 2.1;
218330 expect(@floor(a) == 2);
......@@ -221,6 +333,14 @@ fn testFloor() void {
221333 var a: f64 = 3.5;
222334 expect(@floor(a) == 3);
223335 }
336 {
337 var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
338 var result = @floor(v);
339 expect(math.approxEq(f32, @floor(@as(f32, 1.1)), result[0], epsilon));
340 expect(math.approxEq(f32, @floor(@as(f32, -2.2)), result[1], epsilon));
341 expect(math.approxEq(f32, @floor(@as(f32, 0.3)), result[2], epsilon));
342 expect(math.approxEq(f32, @floor(@as(f32, -0.4)), result[3], epsilon));
343 }
224344}
225345
226346test "@ceil" {
......@@ -229,8 +349,12 @@ test "@ceil" {
229349}
230350
231351fn testCeil() void {
232 // TODO test f16, f128, and c_longdouble
352 // TODO test f128, and c_longdouble
233353 // https://github.com/ziglang/zig/issues/4026
354 {
355 var a: f16 = 2.1;
356 expect(@ceil(a) == 3);
357 }
234358 {
235359 var a: f32 = 2.1;
236360 expect(@ceil(a) == 3);
......@@ -239,6 +363,14 @@ fn testCeil() void {
239363 var a: f64 = 3.5;
240364 expect(@ceil(a) == 4);
241365 }
366 {
367 var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
368 var result = @ceil(v);
369 expect(math.approxEq(f32, @ceil(@as(f32, 1.1)), result[0], epsilon));
370 expect(math.approxEq(f32, @ceil(@as(f32, -2.2)), result[1], epsilon));
371 expect(math.approxEq(f32, @ceil(@as(f32, 0.3)), result[2], epsilon));
372 expect(math.approxEq(f32, @ceil(@as(f32, -0.4)), result[3], epsilon));
373 }
242374}
243375
244376test "@trunc" {
......@@ -247,8 +379,12 @@ test "@trunc" {
247379}
248380
249381fn testTrunc() void {
250 // TODO test f16, f128, and c_longdouble
382 // TODO test f128, and c_longdouble
251383 // https://github.com/ziglang/zig/issues/4026
384 {
385 var a: f16 = 2.1;
386 expect(@trunc(a) == 2);
387 }
252388 {
253389 var a: f32 = 2.1;
254390 expect(@trunc(a) == 2);
......@@ -257,10 +393,18 @@ fn testTrunc() void {
257393 var a: f64 = -3.5;
258394 expect(@trunc(a) == -3);
259395 }
396 {
397 var v: @Vector(4, f32) = [_]f32{1.1, -2.2, 0.3, -0.4};
398 var result = @trunc(v);
399 expect(math.approxEq(f32, @trunc(@as(f32, 1.1)), result[0], epsilon));
400 expect(math.approxEq(f32, @trunc(@as(f32, -2.2)), result[1], epsilon));
401 expect(math.approxEq(f32, @trunc(@as(f32, 0.3)), result[2], epsilon));
402 expect(math.approxEq(f32, @trunc(@as(f32, -0.4)), result[3], epsilon));
403 }
260404}
261405
262406// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)
263//test "@nearbyInt" {
407//test "@nearbyint" {
264408// comptime testNearbyInt();
265409// testNearbyInt();
266410//}
......@@ -270,10 +414,10 @@ fn testTrunc() void {
270414// // https://github.com/ziglang/zig/issues/4026
271415// {
272416// var a: f32 = 2.1;
273// expect(@nearbyInt(a) == 2);
417// expect(@nearbyint(a) == 2);
274418// }
275419// {
276420// var a: f64 = -3.75;
277// expect(@nearbyInt(a) == -4);
421// expect(@nearbyint(a) == -4);
278422// }
279423//}