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" {...@@ -8130,8 +8130,8 @@ test "vector @splat" {
8130 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.8130 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
8131 </p>8131 </p>
8132 {#header_close#}8132 {#header_close#}
8133 {#header_open|@ln#}8133 {#header_open|@log#}
8134 <pre>{#syntax#}@ln(value: var) @TypeOf(value){#endsyntax#}</pre>8134 <pre>{#syntax#}@log(value: var) @TypeOf(value){#endsyntax#}</pre>
8135 <p>8135 <p>
8136 Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction8136 Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction
8137 when available.8137 when available.
src/all_types.hpp+1-1
...@@ -1680,7 +1680,7 @@ enum BuiltinFnId {...@@ -1680,7 +1680,7 @@ enum BuiltinFnId {
1680 BuiltinFnIdCos,1680 BuiltinFnIdCos,
1681 BuiltinFnIdExp,1681 BuiltinFnIdExp,
1682 BuiltinFnIdExp2,1682 BuiltinFnIdExp2,
1683 BuiltinFnIdLn,1683 BuiltinFnIdLog,
1684 BuiltinFnIdLog2,1684 BuiltinFnIdLog2,
1685 BuiltinFnIdLog10,1685 BuiltinFnIdLog10,
1686 BuiltinFnIdFabs,1686 BuiltinFnIdFabs,
src/codegen.cpp+2-2
...@@ -764,7 +764,7 @@ static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn...@@ -764,7 +764,7 @@ static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn
764 name = "fma";764 name = "fma";
765 num_args = 3;765 num_args = 3;
766 } else if (fn_id == ZigLLVMFnIdFloatOp) {766 } else if (fn_id == ZigLLVMFnIdFloatOp) {
767 name = float_op_to_name(op, true);767 name = float_op_to_name(op);
768 num_args = 1;768 num_args = 1;
769 } else {769 } else {
770 zig_unreachable();770 zig_unreachable();
...@@ -8205,7 +8205,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -8205,7 +8205,7 @@ static void define_builtin_fns(CodeGen *g) {
8205 create_builtin_fn(g, BuiltinFnIdCos, "cos", 1);8205 create_builtin_fn(g, BuiltinFnIdCos, "cos", 1);
8206 create_builtin_fn(g, BuiltinFnIdExp, "exp", 1);8206 create_builtin_fn(g, BuiltinFnIdExp, "exp", 1);
8207 create_builtin_fn(g, BuiltinFnIdExp2, "exp2", 1);8207 create_builtin_fn(g, BuiltinFnIdExp2, "exp2", 1);
8208 create_builtin_fn(g, BuiltinFnIdLn, "ln", 1);8208 create_builtin_fn(g, BuiltinFnIdLog, "log", 1);
8209 create_builtin_fn(g, BuiltinFnIdLog2, "log2", 1);8209 create_builtin_fn(g, BuiltinFnIdLog2, "log2", 1);
8210 create_builtin_fn(g, BuiltinFnIdLog10, "log10", 1);8210 create_builtin_fn(g, BuiltinFnIdLog10, "log10", 1);
8211 create_builtin_fn(g, BuiltinFnIdFabs, "fabs", 1);8211 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...@@ -3125,9 +3125,7 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode
3125//TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign,3125//TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign,
3126// lround, llround, lrint, llrint3126// lround, llround, lrint, llrint
3127// So far this is only non-complicated type functions.3127// So far this is only non-complicated type functions.
3128const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {3128const char *float_op_to_name(BuiltinFnId op) {
3129 const bool b = llvm_name;
3130
3131 switch (op) {3129 switch (op) {
3132 case BuiltinFnIdSqrt:3130 case BuiltinFnIdSqrt:
3133 return "sqrt";3131 return "sqrt";
...@@ -3139,8 +3137,8 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {...@@ -3139,8 +3137,8 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
3139 return "exp";3137 return "exp";
3140 case BuiltinFnIdExp2:3138 case BuiltinFnIdExp2:
3141 return "exp2";3139 return "exp2";
3142 case BuiltinFnIdLn:3140 case BuiltinFnIdLog:
3143 return b ? "log" : "ln";3141 return "log";
3144 case BuiltinFnIdLog10:3142 case BuiltinFnIdLog10:
3145 return "log10";3143 return "log10";
3146 case BuiltinFnIdLog2:3144 case BuiltinFnIdLog2:
...@@ -3154,7 +3152,7 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {...@@ -3154,7 +3152,7 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
3154 case BuiltinFnIdTrunc:3152 case BuiltinFnIdTrunc:
3155 return "trunc";3153 return "trunc";
3156 case BuiltinFnIdNearbyInt:3154 case BuiltinFnIdNearbyInt:
3157 return b ? "nearbyint" : "nearbyInt";3155 return "nearbyint";
3158 case BuiltinFnIdRound:3156 case BuiltinFnIdRound:
3159 return "round";3157 return "round";
3160 default:3158 default:
...@@ -5497,7 +5495,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5497,7 +5495,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5497 case BuiltinFnIdCos:5495 case BuiltinFnIdCos:
5498 case BuiltinFnIdExp:5496 case BuiltinFnIdExp:
5499 case BuiltinFnIdExp2:5497 case BuiltinFnIdExp2:
5500 case BuiltinFnIdLn:5498 case BuiltinFnIdLog:
5501 case BuiltinFnIdLog2:5499 case BuiltinFnIdLog2:
5502 case BuiltinFnIdLog10:5500 case BuiltinFnIdLog10:
5503 case BuiltinFnIdFabs:5501 case BuiltinFnIdFabs:
...@@ -27626,7 +27624,7 @@ static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, I...@@ -27626,7 +27624,7 @@ static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, I
27626 return result;27624 return result;
27627}27625}
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,
27630 ZigValue *op, ZigValue *out_val)27628 ZigValue *op, ZigValue *out_val)
27631{27629{
27632 assert(ira && source_instr && float_type && out_val && op);27630 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...@@ -27653,24 +27651,49 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
27653 out_val->data.x_f16 = f16_sqrt(op->data.x_f16);27651 out_val->data.x_f16 = f16_sqrt(op->data.x_f16);
27654 break;27652 break;
27655 case BuiltinFnIdSin:27653 case BuiltinFnIdSin:
27654 out_val->data.x_f16 = zig_double_to_f16(sin(zig_f16_to_double(op->data.x_f16)));
27655 break;
27656 case BuiltinFnIdCos:27656 case BuiltinFnIdCos:
27657 out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16)));
27658 break;
27657 case BuiltinFnIdExp:27659 case BuiltinFnIdExp:
27660 out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16)));
27661 break;
27658 case BuiltinFnIdExp2:27662 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;
27660 case BuiltinFnIdLog10:27668 case BuiltinFnIdLog10:
27669 out_val->data.x_f16 = zig_double_to_f16(log10(zig_f16_to_double(op->data.x_f16)));
27670 break;
27661 case BuiltinFnIdLog2:27671 case BuiltinFnIdLog2:
27672 out_val->data.x_f16 = zig_double_to_f16(log2(zig_f16_to_double(op->data.x_f16)));
27673 break;
27662 case BuiltinFnIdFabs:27674 case BuiltinFnIdFabs:
27675 out_val->data.x_f16 = zig_double_to_f16(fabs(zig_f16_to_double(op->data.x_f16)));
27676 break;
27663 case BuiltinFnIdFloor:27677 case BuiltinFnIdFloor:
27678 out_val->data.x_f16 = zig_double_to_f16(floor(zig_f16_to_double(op->data.x_f16)));
27679 break;
27664 case BuiltinFnIdCeil:27680 case BuiltinFnIdCeil:
27681 out_val->data.x_f16 = zig_double_to_f16(ceil(zig_f16_to_double(op->data.x_f16)));
27682 break;
27665 case BuiltinFnIdTrunc:27683 case BuiltinFnIdTrunc:
27684 out_val->data.x_f16 = zig_double_to_f16(trunc(zig_f16_to_double(op->data.x_f16)));
27685 break;
27666 case BuiltinFnIdNearbyInt:27686 case BuiltinFnIdNearbyInt:
27687 out_val->data.x_f16 = zig_double_to_f16(nearbyint(zig_f16_to_double(op->data.x_f16)));
27688 break;
27667 case BuiltinFnIdRound:27689 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;
27669 default:27692 default:
27670 zig_unreachable();27693 zig_unreachable();
27671 };27694 };
27672 break;27695 break;
27673 };27696 }
27674 case 32: {27697 case 32: {
27675 switch (fop) {27698 switch (fop) {
27676 case BuiltinFnIdSqrt:27699 case BuiltinFnIdSqrt:
...@@ -27688,7 +27711,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti...@@ -27688,7 +27711,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
27688 case BuiltinFnIdExp2:27711 case BuiltinFnIdExp2:
27689 out_val->data.x_f32 = exp2f(op->data.x_f32);27712 out_val->data.x_f32 = exp2f(op->data.x_f32);
27690 break;27713 break;
27691 case BuiltinFnIdLn:27714 case BuiltinFnIdLog:
27692 out_val->data.x_f32 = logf(op->data.x_f32);27715 out_val->data.x_f32 = logf(op->data.x_f32);
27693 break;27716 break;
27694 case BuiltinFnIdLog10:27717 case BuiltinFnIdLog10:
...@@ -27719,7 +27742,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti...@@ -27719,7 +27742,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
27719 zig_unreachable();27742 zig_unreachable();
27720 };27743 };
27721 break;27744 break;
27722 };27745 }
27723 case 64: {27746 case 64: {
27724 switch (fop) {27747 switch (fop) {
27725 case BuiltinFnIdSqrt:27748 case BuiltinFnIdSqrt:
...@@ -27737,7 +27760,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti...@@ -27737,7 +27760,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
27737 case BuiltinFnIdExp2:27760 case BuiltinFnIdExp2:
27738 out_val->data.x_f64 = exp2(op->data.x_f64);27761 out_val->data.x_f64 = exp2(op->data.x_f64);
27739 break;27762 break;
27740 case BuiltinFnIdLn:27763 case BuiltinFnIdLog:
27741 out_val->data.x_f64 = log(op->data.x_f64);27764 out_val->data.x_f64 = log(op->data.x_f64);
27742 break;27765 break;
27743 case BuiltinFnIdLog10:27766 case BuiltinFnIdLog10:
...@@ -27768,7 +27791,11 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti...@@ -27768,7 +27791,11 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
27768 zig_unreachable();27791 zig_unreachable();
27769 }27792 }
27770 break;27793 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)));
27772 case 128: {27799 case 128: {
27773 float128_t *out, *in;27800 float128_t *out, *in;
27774 if (float_type->id == ZigTypeIdComptimeFloat) {27801 if (float_type->id == ZigTypeIdComptimeFloat) {
...@@ -27787,7 +27814,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti...@@ -27787,7 +27814,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
27787 case BuiltinFnIdCos:27814 case BuiltinFnIdCos:
27788 case BuiltinFnIdExp:27815 case BuiltinFnIdExp:
27789 case BuiltinFnIdExp2:27816 case BuiltinFnIdExp2:
27790 case BuiltinFnIdLn:27817 case BuiltinFnIdLog:
27791 case BuiltinFnIdLog10:27818 case BuiltinFnIdLog10:
27792 case BuiltinFnIdLog2:27819 case BuiltinFnIdLog2:
27793 case BuiltinFnIdFabs:27820 case BuiltinFnIdFabs:
...@@ -27795,15 +27822,19 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti...@@ -27795,15 +27822,19 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
27795 case BuiltinFnIdCeil:27822 case BuiltinFnIdCeil:
27796 case BuiltinFnIdTrunc:27823 case BuiltinFnIdTrunc:
27797 case BuiltinFnIdRound:27824 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)));
27799 default:27828 default:
27800 zig_unreachable();27829 zig_unreachable();
27801 }27830 }
27802 break;27831 break;
27803 };27832 }
27804 default:27833 default:
27805 zig_unreachable();27834 zig_unreachable();
27806 }27835 }
27836 out_val->special = ConstValSpecialStatic;
27837 return nullptr;
27807}27838}
2780827839
27809static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) {27840static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) {
...@@ -27838,17 +27869,27 @@ static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstruct...@@ -27838,17 +27869,27 @@ static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstruct
27838 expand_undef_array(ira->codegen, out_val);27869 expand_undef_array(ira->codegen, out_val);
27839 size_t len = operand_type->data.vector.len;27870 size_t len = operand_type->data.vector.len;
27840 for (size_t i = 0; i < len; i += 1) {27871 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];
27842 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i];27873 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);
27844 ir_assert(float_out_val->type == scalar_type, &instruction->base);27875 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 }
27846 float_out_val->type = scalar_type;27883 float_out_val->type = scalar_type;
27847 }27884 }
27848 out_val->type = operand_type;27885 out_val->type = operand_type;
27849 out_val->special = ConstValSpecialStatic;27886 out_val->special = ConstValSpecialStatic;
27850 } else {27887 } 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 }
27852 }27893 }
27853 return result;27894 return result;
27854 }27895 }
src/ir.hpp+1-1
...@@ -33,7 +33,7 @@ bool ir_has_side_effects(IrInstruction *instruction);...@@ -33,7 +33,7 @@ bool ir_has_side_effects(IrInstruction *instruction);
33struct IrAnalyze;33struct IrAnalyze;
34ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,34ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
35 AstNode *source_node);35 AstNode *source_node);
36const char *float_op_to_name(BuiltinFnId op, bool llvm_name);36const char *float_op_to_name(BuiltinFnId op);
3737
38// for debugging purposes38// for debugging purposes
39void dbg_ir_break(const char *src_file, uint32_t line);39void 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...@@ -2005,7 +2005,7 @@ static void ir_print_add_implicit_return_type(IrPrint *irp, IrInstructionAddImpl
2005}2005}
20062006
2007static void ir_print_float_op(IrPrint *irp, IrInstructionFloatOp *instruction) {2007static 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));
2009 ir_print_other_instruction(irp, instruction->operand);2009 ir_print_other_instruction(irp, instruction->operand);
2010 fprintf(irp->f, ")");2010 fprintf(irp->f, ")");
2011}2011}
test/stage1/behavior/floatop.zig+166-22
...@@ -4,6 +4,8 @@ const math = std.math;...@@ -4,6 +4,8 @@ const math = std.math;
4const pi = std.math.pi;4const pi = std.math.pi;
5const e = std.math.e;5const e = std.math.e;
66
7const epsilon = 0.000001;
8
7test "@sqrt" {9test "@sqrt" {
8 comptime testSqrt();10 comptime testSqrt();
9 testSqrt();11 testSqrt();
...@@ -17,6 +19,8 @@ fn testSqrt() void {...@@ -17,6 +19,8 @@ fn testSqrt() void {
17 {19 {
18 var a: f32 = 9;20 var a: f32 = 9;
19 expect(@sqrt(a) == 3);21 expect(@sqrt(a) == 3);
22 var b: f32 = 1.1;
23 expect(math.approxEq(f32, @sqrt(b), 1.0488088481701516, epsilon));
20 }24 }
21 {25 {
22 var a: f64 = 25;26 var a: f64 = 25;
...@@ -31,12 +35,18 @@ fn testSqrt() void {...@@ -31,12 +35,18 @@ fn testSqrt() void {
31 // var a: f128 = 49;35 // var a: f128 = 49;
32 // expect(@sqrt(a) == 7);36 // expect(@sqrt(a) == 7);
33 //}37 //}
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 }
34}46}
3547
36test "more @sqrt f16 tests" {48test "more @sqrt f16 tests" {
37 // TODO these are not all passing at comptime49 // TODO these are not all passing at comptime
38 const epsilon = 0.000001;
39
40 expect(@sqrt(@as(f16, 0.0)) == 0.0);50 expect(@sqrt(@as(f16, 0.0)) == 0.0);
41 expect(math.approxEq(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));51 expect(math.approxEq(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));
42 expect(math.approxEq(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon));52 expect(math.approxEq(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon));
...@@ -61,8 +71,12 @@ test "@sin" {...@@ -61,8 +71,12 @@ test "@sin" {
61}71}
6272
63fn testSin() void {73fn testSin() void {
64 // TODO test f16, f128, and c_longdouble74 // TODO test f128, and c_longdouble
65 // https://github.com/ziglang/zig/issues/402675 // https://github.com/ziglang/zig/issues/4026
76 {
77 var a: f16 = 0;
78 expect(@sin(a) == 0);
79 }
66 {80 {
67 var a: f32 = 0;81 var a: f32 = 0;
68 expect(@sin(a) == 0);82 expect(@sin(a) == 0);
...@@ -71,6 +85,14 @@ fn testSin() void {...@@ -71,6 +85,14 @@ fn testSin() void {
71 var a: f64 = 0;85 var a: f64 = 0;
72 expect(@sin(a) == 0);86 expect(@sin(a) == 0);
73 }87 }
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 }
74}96}
7597
76test "@cos" {98test "@cos" {
...@@ -79,8 +101,12 @@ test "@cos" {...@@ -79,8 +101,12 @@ test "@cos" {
79}101}
80102
81fn testCos() void {103fn testCos() void {
82 // TODO test f16, f128, and c_longdouble104 // TODO test f128, and c_longdouble
83 // https://github.com/ziglang/zig/issues/4026105 // https://github.com/ziglang/zig/issues/4026
106 {
107 var a: f16 = 0;
108 expect(@cos(a) == 1);
109 }
84 {110 {
85 var a: f32 = 0;111 var a: f32 = 0;
86 expect(@cos(a) == 1);112 expect(@cos(a) == 1);
...@@ -89,6 +115,14 @@ fn testCos() void {...@@ -89,6 +115,14 @@ fn testCos() void {
89 var a: f64 = 0;115 var a: f64 = 0;
90 expect(@cos(a) == 1);116 expect(@cos(a) == 1);
91 }117 }
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 }
92}126}
93127
94test "@exp" {128test "@exp" {
...@@ -97,8 +131,12 @@ test "@exp" {...@@ -97,8 +131,12 @@ test "@exp" {
97}131}
98132
99fn testExp() void {133fn testExp() void {
100 // TODO test f16, f128, and c_longdouble134 // TODO test f128, and c_longdouble
101 // https://github.com/ziglang/zig/issues/4026135 // https://github.com/ziglang/zig/issues/4026
136 {
137 var a: f16 = 0;
138 expect(@exp(a) == 1);
139 }
102 {140 {
103 var a: f32 = 0;141 var a: f32 = 0;
104 expect(@exp(a) == 1);142 expect(@exp(a) == 1);
...@@ -107,6 +145,14 @@ fn testExp() void {...@@ -107,6 +145,14 @@ fn testExp() void {
107 var a: f64 = 0;145 var a: f64 = 0;
108 expect(@exp(a) == 1);146 expect(@exp(a) == 1);
109 }147 }
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 }
110}156}
111157
112test "@exp2" {158test "@exp2" {
...@@ -115,8 +161,12 @@ test "@exp2" {...@@ -115,8 +161,12 @@ test "@exp2" {
115}161}
116162
117fn testExp2() void {163fn testExp2() void {
118 // TODO test f16, f128, and c_longdouble164 // TODO test f128, and c_longdouble
119 // https://github.com/ziglang/zig/issues/4026165 // https://github.com/ziglang/zig/issues/4026
166 {
167 var a: f16 = 2;
168 expect(@exp2(a) == 4);
169 }
120 {170 {
121 var a: f32 = 2;171 var a: f32 = 2;
122 expect(@exp2(a) == 4);172 expect(@exp2(a) == 4);
...@@ -125,25 +175,45 @@ fn testExp2() void {...@@ -125,25 +175,45 @@ fn testExp2() void {
125 var a: f64 = 2;175 var a: f64 = 2;
126 expect(@exp2(a) == 4);176 expect(@exp2(a) == 4);
127 }177 }
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 }
128}186}
129187
130test "@ln" {188test "@log" {
131 // Old musl (and glibc?), and our current math.ln implementation do not return 1189 // Old musl (and glibc?), and our current math.ln implementation do not return 1
132 // so also accept those values.190 // so also accept those values.
133 comptime testLn();191 comptime testLog();
134 testLn();192 testLog();
135}193}
136194
137fn testLn() void {195fn testLog() void {
138 // TODO test f16, f128, and c_longdouble196 // TODO test f128, and c_longdouble
139 // https://github.com/ziglang/zig/issues/4026197 // https://github.com/ziglang/zig/issues/4026
198 {
199 var a: f16 = e;
200 expect(math.approxEq(f16, @log(a), 1, epsilon));
201 }
140 {202 {
141 var a: f32 = e;203 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)));
143 }205 }
144 {206 {
145 var a: f64 = e;207 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));
147 }217 }
148}218}
149219
...@@ -153,8 +223,12 @@ test "@log2" {...@@ -153,8 +223,12 @@ test "@log2" {
153}223}
154224
155fn testLog2() void {225fn testLog2() void {
156 // TODO test f16, f128, and c_longdouble226 // TODO test f128, and c_longdouble
157 // https://github.com/ziglang/zig/issues/4026227 // https://github.com/ziglang/zig/issues/4026
228 {
229 var a: f16 = 4;
230 expect(@log2(a) == 2);
231 }
158 {232 {
159 var a: f32 = 4;233 var a: f32 = 4;
160 expect(@log2(a) == 2);234 expect(@log2(a) == 2);
...@@ -163,6 +237,14 @@ fn testLog2() void {...@@ -163,6 +237,14 @@ fn testLog2() void {
163 var a: f64 = 4;237 var a: f64 = 4;
164 expect(@log2(a) == 2);238 expect(@log2(a) == 2);
165 }239 }
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 }
166}248}
167249
168test "@log10" {250test "@log10" {
...@@ -171,8 +253,12 @@ test "@log10" {...@@ -171,8 +253,12 @@ test "@log10" {
171}253}
172254
173fn testLog10() void {255fn testLog10() void {
174 // TODO test f16, f128, and c_longdouble256 // TODO test f128, and c_longdouble
175 // https://github.com/ziglang/zig/issues/4026257 // https://github.com/ziglang/zig/issues/4026
258 {
259 var a: f16 = 100;
260 expect(@log10(a) == 2);
261 }
176 {262 {
177 var a: f32 = 100;263 var a: f32 = 100;
178 expect(@log10(a) == 2);264 expect(@log10(a) == 2);
...@@ -181,6 +267,14 @@ fn testLog10() void {...@@ -181,6 +267,14 @@ fn testLog10() void {
181 var a: f64 = 1000;267 var a: f64 = 1000;
182 expect(@log10(a) == 3);268 expect(@log10(a) == 3);
183 }269 }
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 }
184}278}
185279
186test "@fabs" {280test "@fabs" {
...@@ -189,8 +283,14 @@ test "@fabs" {...@@ -189,8 +283,14 @@ test "@fabs" {
189}283}
190284
191fn testFabs() void {285fn testFabs() void {
192 // TODO test f16, f128, and c_longdouble286 // TODO test f128, and c_longdouble
193 // https://github.com/ziglang/zig/issues/4026287 // 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 }
194 {294 {
195 var a: f32 = -2.5;295 var a: f32 = -2.5;
196 var b: f32 = 2.5;296 var b: f32 = 2.5;
...@@ -203,6 +303,14 @@ fn testFabs() void {...@@ -203,6 +303,14 @@ fn testFabs() void {
203 expect(@fabs(a) == 2.5);303 expect(@fabs(a) == 2.5);
204 expect(@fabs(b) == 2.5);304 expect(@fabs(b) == 2.5);
205 }305 }
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 }
206}314}
207315
208test "@floor" {316test "@floor" {
...@@ -211,8 +319,12 @@ test "@floor" {...@@ -211,8 +319,12 @@ test "@floor" {
211}319}
212320
213fn testFloor() void {321fn testFloor() void {
214 // TODO test f16, f128, and c_longdouble322 // TODO test f128, and c_longdouble
215 // https://github.com/ziglang/zig/issues/4026323 // https://github.com/ziglang/zig/issues/4026
324 {
325 var a: f16 = 2.1;
326 expect(@floor(a) == 2);
327 }
216 {328 {
217 var a: f32 = 2.1;329 var a: f32 = 2.1;
218 expect(@floor(a) == 2);330 expect(@floor(a) == 2);
...@@ -221,6 +333,14 @@ fn testFloor() void {...@@ -221,6 +333,14 @@ fn testFloor() void {
221 var a: f64 = 3.5;333 var a: f64 = 3.5;
222 expect(@floor(a) == 3);334 expect(@floor(a) == 3);
223 }335 }
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 }
224}344}
225345
226test "@ceil" {346test "@ceil" {
...@@ -229,8 +349,12 @@ test "@ceil" {...@@ -229,8 +349,12 @@ test "@ceil" {
229}349}
230350
231fn testCeil() void {351fn testCeil() void {
232 // TODO test f16, f128, and c_longdouble352 // TODO test f128, and c_longdouble
233 // https://github.com/ziglang/zig/issues/4026353 // https://github.com/ziglang/zig/issues/4026
354 {
355 var a: f16 = 2.1;
356 expect(@ceil(a) == 3);
357 }
234 {358 {
235 var a: f32 = 2.1;359 var a: f32 = 2.1;
236 expect(@ceil(a) == 3);360 expect(@ceil(a) == 3);
...@@ -239,6 +363,14 @@ fn testCeil() void {...@@ -239,6 +363,14 @@ fn testCeil() void {
239 var a: f64 = 3.5;363 var a: f64 = 3.5;
240 expect(@ceil(a) == 4);364 expect(@ceil(a) == 4);
241 }365 }
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 }
242}374}
243375
244test "@trunc" {376test "@trunc" {
...@@ -247,8 +379,12 @@ test "@trunc" {...@@ -247,8 +379,12 @@ test "@trunc" {
247}379}
248380
249fn testTrunc() void {381fn testTrunc() void {
250 // TODO test f16, f128, and c_longdouble382 // TODO test f128, and c_longdouble
251 // https://github.com/ziglang/zig/issues/4026383 // https://github.com/ziglang/zig/issues/4026
384 {
385 var a: f16 = 2.1;
386 expect(@trunc(a) == 2);
387 }
252 {388 {
253 var a: f32 = 2.1;389 var a: f32 = 2.1;
254 expect(@trunc(a) == 2);390 expect(@trunc(a) == 2);
...@@ -257,10 +393,18 @@ fn testTrunc() void {...@@ -257,10 +393,18 @@ fn testTrunc() void {
257 var a: f64 = -3.5;393 var a: f64 = -3.5;
258 expect(@trunc(a) == -3);394 expect(@trunc(a) == -3);
259 }395 }
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 }
260}404}
261405
262// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)406// 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" {
264// comptime testNearbyInt();408// comptime testNearbyInt();
265// testNearbyInt();409// testNearbyInt();
266//}410//}
...@@ -270,10 +414,10 @@ fn testTrunc() void {...@@ -270,10 +414,10 @@ fn testTrunc() void {
270// // https://github.com/ziglang/zig/issues/4026414// // https://github.com/ziglang/zig/issues/4026
271// {415// {
272// var a: f32 = 2.1;416// var a: f32 = 2.1;
273// expect(@nearbyInt(a) == 2);417// expect(@nearbyint(a) == 2);
274// }418// }
275// {419// {
276// var a: f64 = -3.75;420// var a: f64 = -3.75;
277// expect(@nearbyInt(a) == -4);421// expect(@nearbyint(a) == -4);
278// }422// }
279//}423//}