authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-06-07 22:56:57-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-06-14 00:24:25-04:00
log7f0620a20fc431717d017d0c19f1e1f29723d93f
treec8121edd20aa67bf5a22be1f817f679dcfbbdb52
parent6a93dda3e1c0ff5f400da25a5d14c907fc9a6fdf

partial implementation of printing floating point numbers with errol3

also add bitCast builtin function. closes #387

27 files changed, 3547 insertions(+), 866 deletions(-)

CMakeLists.txt+7-2
......@@ -216,12 +216,17 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/dwarf.zig" DESTINATION "${ZIG_STD_DEST}")
216216install(FILES "${CMAKE_SOURCE_DIR}/std/elf.zig" DESTINATION "${ZIG_STD_DEST}")
217217install(FILES "${CMAKE_SOURCE_DIR}/std/empty.zig" DESTINATION "${ZIG_STD_DEST}")
218218install(FILES "${CMAKE_SOURCE_DIR}/std/endian.zig" DESTINATION "${ZIG_STD_DEST}")
219install(FILES "${CMAKE_SOURCE_DIR}/std/fmt.zig" DESTINATION "${ZIG_STD_DEST}")
219install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/index.zig" DESTINATION "${ZIG_STD_DEST}/fmt")
220install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/index.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol")
221install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/enum3.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol")
222install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/lookup.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol")
220223install(FILES "${CMAKE_SOURCE_DIR}/std/hash_map.zig" DESTINATION "${ZIG_STD_DEST}")
221224install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}")
222225install(FILES "${CMAKE_SOURCE_DIR}/std/io.zig" DESTINATION "${ZIG_STD_DEST}")
223226install(FILES "${CMAKE_SOURCE_DIR}/std/linked_list.zig" DESTINATION "${ZIG_STD_DEST}")
224install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}")
227install(FILES "${CMAKE_SOURCE_DIR}/std/math/index.zig" DESTINATION "${ZIG_STD_DEST}/math")
228install(FILES "${CMAKE_SOURCE_DIR}/std/math/frexp.zig" DESTINATION "${ZIG_STD_DEST}/math")
229install(FILES "${CMAKE_SOURCE_DIR}/std/math/fabs.zig" DESTINATION "${ZIG_STD_DEST}/math")
225230install(FILES "${CMAKE_SOURCE_DIR}/std/mem.zig" DESTINATION "${ZIG_STD_DEST}")
226231install(FILES "${CMAKE_SOURCE_DIR}/std/net.zig" DESTINATION "${ZIG_STD_DEST}")
227232install(FILES "${CMAKE_SOURCE_DIR}/std/os/child_process.zig" DESTINATION "${ZIG_STD_DEST}/os")
src/all_types.hpp+9
......@@ -1216,6 +1216,7 @@ enum BuiltinFnId {
12161216 BuiltinFnIdSetGlobalLinkage,
12171217 BuiltinFnIdPanic,
12181218 BuiltinFnIdPtrCast,
1219 BuiltinFnIdBitCast,
12191220 BuiltinFnIdIntToPtr,
12201221 BuiltinFnIdEnumTagName,
12211222 BuiltinFnIdFieldParentPtr,
......@@ -1800,6 +1801,7 @@ enum IrInstructionId {
18001801 IrInstructionIdTestComptime,
18011802 IrInstructionIdInitEnum,
18021803 IrInstructionIdPtrCast,
1804 IrInstructionIdBitCast,
18031805 IrInstructionIdWidenOrShorten,
18041806 IrInstructionIdIntToPtr,
18051807 IrInstructionIdPtrToInt,
......@@ -2448,6 +2450,13 @@ struct IrInstructionPtrCast {
24482450 IrInstruction *ptr;
24492451};
24502452
2453struct IrInstructionBitCast {
2454 IrInstruction base;
2455
2456 IrInstruction *dest_type;
2457 IrInstruction *value;
2458};
2459
24512460struct IrInstructionWidenOrShorten {
24522461 IrInstruction base;
24532462
src/bignum.cpp+74
......@@ -459,3 +459,77 @@ uint32_t bignum_clz(BigNum *bignum, uint32_t bit_count) {
459459 }
460460 return result;
461461}
462
463void bignum_write_twos_complement(BigNum *bn, uint8_t *buf, int bit_count, bool is_big_endian) {
464 assert(bn->kind == BigNumKindInt);
465 uint64_t x = bignum_to_twos_complement(bn);
466
467 int byte_count = (bit_count + 7) / 8;
468 for (int i = 0; i < byte_count; i += 1) {
469 uint8_t le_byte = (x >> (i * 8)) & 0xff;
470 if (is_big_endian) {
471 buf[byte_count - i - 1] = le_byte;
472 } else {
473 buf[i] = le_byte;
474 }
475 }
476}
477
478void bignum_read_twos_complement(BigNum *bn, uint8_t *buf, int bit_count, bool is_big_endian, bool is_signed) {
479 int byte_count = (bit_count + 7) / 8;
480
481 uint64_t twos_comp = 0;
482 for (int i = 0; i < byte_count; i += 1) {
483 uint8_t be_byte;
484 if (is_big_endian) {
485 be_byte = buf[i];
486 } else {
487 be_byte = buf[byte_count - i - 1];
488 }
489
490 twos_comp <<= 8;
491 twos_comp |= be_byte;
492 }
493
494 uint8_t be_byte = buf[is_big_endian ? 0 : byte_count - 1];
495 if (is_signed && ((be_byte >> 7) & 0x1) != 0) {
496 bn->is_negative = true;
497 uint64_t mask = 0;
498 for (int i = 0; i < bit_count; i += 1) {
499 mask <<= 1;
500 mask |= 1;
501 }
502 bn->data.x_uint = ((~twos_comp) & mask) + 1;
503 } else {
504 bn->data.x_uint = twos_comp;
505 }
506 bn->kind = BigNumKindInt;
507}
508
509void bignum_write_ieee597(BigNum *bn, uint8_t *buf, int bit_count, bool is_big_endian) {
510 assert(bn->kind == BigNumKindFloat);
511 if (bit_count == 32) {
512 float f32 = bn->data.x_float;
513 memcpy(buf, &f32, 4);
514 } else if (bit_count == 64) {
515 double f64 = bn->data.x_float;
516 memcpy(buf, &f64, 8);
517 } else {
518 zig_unreachable();
519 }
520}
521
522void bignum_read_ieee597(BigNum *bn, uint8_t *buf, int bit_count, bool is_big_endian) {
523 bn->kind = BigNumKindFloat;
524 if (bit_count == 32) {
525 float f32;
526 memcpy(&f32, buf, 4);
527 bn->data.x_float = f32;
528 } else if (bit_count == 64) {
529 double f64;
530 memcpy(&f64, buf, 8);
531 bn->data.x_float = f64;
532 } else {
533 zig_unreachable();
534 }
535}
src/bignum.hpp+5
......@@ -32,6 +32,11 @@ void bignum_init_bignum(BigNum *dest, BigNum *src);
3232bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed);
3333uint64_t bignum_to_twos_complement(BigNum *bn);
3434
35void bignum_write_twos_complement(BigNum *bn, uint8_t *buf, int bit_count, bool is_big_endian);
36void bignum_write_ieee597(BigNum *bn, uint8_t *buf, int bit_count, bool is_big_endian);
37void bignum_read_twos_complement(BigNum *bn, uint8_t *buf, int bit_count, bool is_big_endian, bool is_signed);
38void bignum_read_ieee597(BigNum *bn, uint8_t *buf, int bit_count, bool is_big_endian);
39
3540// returns true if overflow happened
3641bool bignum_add(BigNum *dest, BigNum *op1, BigNum *op2);
3742bool bignum_sub(BigNum *dest, BigNum *op1, BigNum *op2);
src/codegen.cpp+11
......@@ -1693,6 +1693,14 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
16931693 return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");
16941694}
16951695
1696static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable,
1697 IrInstructionBitCast *instruction)
1698{
1699 TypeTableEntry *wanted_type = instruction->base.value.type;
1700 LLVMValueRef value = ir_llvm_value(g, instruction->value);
1701 return LLVMBuildBitCast(g->builder, value, wanted_type->type_ref, "");
1702}
1703
16961704static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
16971705 IrInstructionWidenOrShorten *instruction)
16981706{
......@@ -3180,6 +3188,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
31803188 return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
31813189 case IrInstructionIdPtrCast:
31823190 return ir_render_ptr_cast(g, executable, (IrInstructionPtrCast *)instruction);
3191 case IrInstructionIdBitCast:
3192 return ir_render_bit_cast(g, executable, (IrInstructionBitCast *)instruction);
31833193 case IrInstructionIdWidenOrShorten:
31843194 return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
31853195 case IrInstructionIdPtrToInt:
......@@ -4514,6 +4524,7 @@ static void define_builtin_fns(CodeGen *g) {
45144524 create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
45154525 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
45164526 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);
4527 create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2);
45174528 create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2);
45184529 create_builtin_fn(g, BuiltinFnIdEnumTagName, "enumTagName", 1);
45194530 create_builtin_fn(g, BuiltinFnIdFieldParentPtr, "fieldParentPtr", 3);
src/ir.cpp+263
......@@ -469,6 +469,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCast *) {
469469 return IrInstructionIdPtrCast;
470470}
471471
472static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
473 return IrInstructionIdBitCast;
474}
475
472476static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
473477 return IrInstructionIdWidenOrShorten;
474478}
......@@ -1922,6 +1926,20 @@ static IrInstruction *ir_build_ptr_cast(IrBuilder *irb, Scope *scope, AstNode *s
19221926 return &instruction->base;
19231927}
19241928
1929static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
1930 IrInstruction *dest_type, IrInstruction *value)
1931{
1932 IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>(
1933 irb, scope, source_node);
1934 instruction->dest_type = dest_type;
1935 instruction->value = value;
1936
1937 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block);
1938 ir_ref_instruction(value, irb->current_basic_block);
1939
1940 return &instruction->base;
1941}
1942
19251943static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, AstNode *source_node,
19261944 IrInstruction *target)
19271945{
......@@ -2704,6 +2722,16 @@ static IrInstruction *ir_instruction_ptrcast_get_dep(IrInstructionPtrCast *instr
27042722 }
27052723}
27062724
2725static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction,
2726 size_t index)
2727{
2728 switch (index) {
2729 case 0: return instruction->value;
2730 case 1: return instruction->dest_type;
2731 default: return nullptr;
2732 }
2733}
2734
27072735static IrInstruction *ir_instruction_widenorshorten_get_dep(IrInstructionWidenOrShorten *instruction, size_t index) {
27082736 switch (index) {
27092737 case 0: return instruction->target;
......@@ -3000,6 +3028,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
30003028 return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
30013029 case IrInstructionIdPtrCast:
30023030 return ir_instruction_ptrcast_get_dep((IrInstructionPtrCast *) instruction, index);
3031 case IrInstructionIdBitCast:
3032 return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index);
30033033 case IrInstructionIdWidenOrShorten:
30043034 return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
30053035 case IrInstructionIdIntToPtr:
......@@ -4301,6 +4331,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43014331
43024332 return ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value);
43034333 }
4334 case BuiltinFnIdBitCast:
4335 {
4336 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4337 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4338 if (arg0_value == irb->codegen->invalid_instruction)
4339 return arg0_value;
4340
4341 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4342 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4343 if (arg1_value == irb->codegen->invalid_instruction)
4344 return arg1_value;
4345
4346 return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4347 }
43044348 case BuiltinFnIdIntToPtr:
43054349 {
43064350 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -13427,6 +13471,222 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc
1342713471 return dest_type;
1342813472}
1342913473
13474static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
13475 assert(val->special == ConstValSpecialStatic);
13476 switch (val->type->id) {
13477 case TypeTableEntryIdInvalid:
13478 case TypeTableEntryIdVar:
13479 case TypeTableEntryIdMetaType:
13480 case TypeTableEntryIdOpaque:
13481 case TypeTableEntryIdBoundFn:
13482 case TypeTableEntryIdArgTuple:
13483 case TypeTableEntryIdNamespace:
13484 case TypeTableEntryIdBlock:
13485 case TypeTableEntryIdUnreachable:
13486 case TypeTableEntryIdNumLitFloat:
13487 case TypeTableEntryIdNumLitInt:
13488 case TypeTableEntryIdUndefLit:
13489 case TypeTableEntryIdNullLit:
13490 zig_unreachable();
13491 case TypeTableEntryIdVoid:
13492 return;
13493 case TypeTableEntryIdBool:
13494 buf[0] = val->data.x_bool ? 1 : 0;
13495 return;
13496 case TypeTableEntryIdInt:
13497 bignum_write_twos_complement(&val->data.x_bignum, buf, val->type->data.integral.bit_count, codegen->is_big_endian);
13498 return;
13499 case TypeTableEntryIdFloat:
13500 bignum_write_ieee597(&val->data.x_bignum, buf, val->type->data.floating.bit_count, codegen->is_big_endian);
13501 return;
13502 case TypeTableEntryIdPointer:
13503 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
13504 BigNum bn;
13505 bignum_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr);
13506 bignum_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian);
13507 return;
13508 } else {
13509 zig_unreachable();
13510 }
13511 case TypeTableEntryIdArray:
13512 zig_panic("TODO buf_write_value_bytes array type");
13513 case TypeTableEntryIdStruct:
13514 zig_panic("TODO buf_write_value_bytes struct type");
13515 case TypeTableEntryIdMaybe:
13516 zig_panic("TODO buf_write_value_bytes maybe type");
13517 case TypeTableEntryIdErrorUnion:
13518 zig_panic("TODO buf_write_value_bytes error union");
13519 case TypeTableEntryIdPureError:
13520 zig_panic("TODO buf_write_value_bytes pure error type");
13521 case TypeTableEntryIdEnum:
13522 zig_panic("TODO buf_write_value_bytes enum type");
13523 case TypeTableEntryIdEnumTag:
13524 zig_panic("TODO buf_write_value_bytes enum tag type");
13525 case TypeTableEntryIdFn:
13526 zig_panic("TODO buf_write_value_bytes fn type");
13527 case TypeTableEntryIdUnion:
13528 zig_panic("TODO buf_write_value_bytes union type");
13529 }
13530 zig_unreachable();
13531}
13532
13533static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
13534 assert(val->special == ConstValSpecialStatic);
13535 switch (val->type->id) {
13536 case TypeTableEntryIdInvalid:
13537 case TypeTableEntryIdVar:
13538 case TypeTableEntryIdMetaType:
13539 case TypeTableEntryIdOpaque:
13540 case TypeTableEntryIdBoundFn:
13541 case TypeTableEntryIdArgTuple:
13542 case TypeTableEntryIdNamespace:
13543 case TypeTableEntryIdBlock:
13544 case TypeTableEntryIdUnreachable:
13545 case TypeTableEntryIdNumLitFloat:
13546 case TypeTableEntryIdNumLitInt:
13547 case TypeTableEntryIdUndefLit:
13548 case TypeTableEntryIdNullLit:
13549 zig_unreachable();
13550 case TypeTableEntryIdVoid:
13551 return;
13552 case TypeTableEntryIdBool:
13553 val->data.x_bool = (buf[0] != 0);
13554 return;
13555 case TypeTableEntryIdInt:
13556 bignum_read_twos_complement(&val->data.x_bignum, buf, val->type->data.integral.bit_count, codegen->is_big_endian,
13557 val->type->data.integral.is_signed);
13558 return;
13559 case TypeTableEntryIdFloat:
13560 bignum_read_ieee597(&val->data.x_bignum, buf, val->type->data.floating.bit_count, codegen->is_big_endian);
13561 return;
13562 case TypeTableEntryIdPointer:
13563 {
13564 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
13565 BigNum bn;
13566 bignum_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian, false);
13567 val->data.x_ptr.data.hard_coded_addr.addr = bignum_to_twos_complement(&bn);
13568 return;
13569 }
13570 case TypeTableEntryIdArray:
13571 zig_panic("TODO buf_read_value_bytes array type");
13572 case TypeTableEntryIdStruct:
13573 zig_panic("TODO buf_read_value_bytes struct type");
13574 case TypeTableEntryIdMaybe:
13575 zig_panic("TODO buf_read_value_bytes maybe type");
13576 case TypeTableEntryIdErrorUnion:
13577 zig_panic("TODO buf_read_value_bytes error union");
13578 case TypeTableEntryIdPureError:
13579 zig_panic("TODO buf_read_value_bytes pure error type");
13580 case TypeTableEntryIdEnum:
13581 zig_panic("TODO buf_read_value_bytes enum type");
13582 case TypeTableEntryIdEnumTag:
13583 zig_panic("TODO buf_read_value_bytes enum tag type");
13584 case TypeTableEntryIdFn:
13585 zig_panic("TODO buf_read_value_bytes fn type");
13586 case TypeTableEntryIdUnion:
13587 zig_panic("TODO buf_read_value_bytes union type");
13588 }
13589 zig_unreachable();
13590}
13591
13592static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
13593 IrInstruction *dest_type_value = instruction->dest_type->other;
13594 TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value);
13595 if (type_is_invalid(dest_type))
13596 return ira->codegen->builtin_types.entry_invalid;
13597
13598 IrInstruction *value = instruction->value->other;
13599 TypeTableEntry *src_type = value->value.type;
13600 if (type_is_invalid(src_type))
13601 return ira->codegen->builtin_types.entry_invalid;
13602
13603 ensure_complete_type(ira->codegen, dest_type);
13604 ensure_complete_type(ira->codegen, src_type);
13605
13606 if (type_is_codegen_pointer(src_type)) {
13607 ir_add_error(ira, value,
13608 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name)));
13609 return ira->codegen->builtin_types.entry_invalid;
13610 }
13611
13612 switch (src_type->id) {
13613 case TypeTableEntryIdInvalid:
13614 case TypeTableEntryIdVar:
13615 case TypeTableEntryIdMetaType:
13616 case TypeTableEntryIdOpaque:
13617 case TypeTableEntryIdBoundFn:
13618 case TypeTableEntryIdArgTuple:
13619 case TypeTableEntryIdNamespace:
13620 case TypeTableEntryIdBlock:
13621 case TypeTableEntryIdUnreachable:
13622 case TypeTableEntryIdNumLitFloat:
13623 case TypeTableEntryIdNumLitInt:
13624 case TypeTableEntryIdUndefLit:
13625 case TypeTableEntryIdNullLit:
13626 ir_add_error(ira, dest_type_value,
13627 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name)));
13628 return ira->codegen->builtin_types.entry_invalid;
13629 default:
13630 break;
13631 }
13632
13633 if (type_is_codegen_pointer(dest_type)) {
13634 ir_add_error(ira, dest_type_value,
13635 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));
13636 return ira->codegen->builtin_types.entry_invalid;
13637 }
13638
13639 switch (dest_type->id) {
13640 case TypeTableEntryIdInvalid:
13641 case TypeTableEntryIdVar:
13642 case TypeTableEntryIdMetaType:
13643 case TypeTableEntryIdOpaque:
13644 case TypeTableEntryIdBoundFn:
13645 case TypeTableEntryIdArgTuple:
13646 case TypeTableEntryIdNamespace:
13647 case TypeTableEntryIdBlock:
13648 case TypeTableEntryIdUnreachable:
13649 case TypeTableEntryIdNumLitFloat:
13650 case TypeTableEntryIdNumLitInt:
13651 case TypeTableEntryIdUndefLit:
13652 case TypeTableEntryIdNullLit:
13653 ir_add_error(ira, dest_type_value,
13654 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));
13655 return ira->codegen->builtin_types.entry_invalid;
13656 default:
13657 break;
13658 }
13659
13660 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type);
13661 uint64_t src_size_bytes = type_size(ira->codegen, src_type);
13662 if (dest_size_bytes != src_size_bytes) {
13663 ir_add_error(ira, &instruction->base,
13664 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64,
13665 buf_ptr(&dest_type->name), dest_size_bytes,
13666 buf_ptr(&src_type->name), src_size_bytes));
13667 return ira->codegen->builtin_types.entry_invalid;
13668 }
13669
13670 if (instr_is_comptime(value)) {
13671 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
13672 if (!val)
13673 return ira->codegen->builtin_types.entry_invalid;
13674
13675 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13676 out_val->type = dest_type;
13677 uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes);
13678 buf_write_value_bytes(ira->codegen, buf, val);
13679 buf_read_value_bytes(ira->codegen, buf, out_val);
13680 return dest_type;
13681 }
13682
13683 IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope,
13684 instruction->base.source_node, nullptr, value);
13685 ir_link_new_instruction(result, &instruction->base);
13686 result->value.type = dest_type;
13687 return dest_type;
13688}
13689
1343013690static TypeTableEntry *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) {
1343113691 IrInstruction *dest_type_value = instruction->dest_type->other;
1343213692 TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value);
......@@ -13697,6 +13957,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1369713957 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
1369813958 case IrInstructionIdPtrCast:
1369913959 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction);
13960 case IrInstructionIdBitCast:
13961 return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
1370013962 case IrInstructionIdIntToPtr:
1370113963 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
1370213964 case IrInstructionIdEnumTagName:
......@@ -13872,6 +14134,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1387214134 case IrInstructionIdTestComptime:
1387314135 case IrInstructionIdInitEnum:
1387414136 case IrInstructionIdPtrCast:
14137 case IrInstructionIdBitCast:
1387514138 case IrInstructionIdWidenOrShorten:
1387614139 case IrInstructionIdPtrToInt:
1387714140 case IrInstructionIdIntToPtr:
src/ir_print.cpp+14-1
......@@ -756,7 +756,7 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction)
756756}
757757
758758static void ir_print_ptr_cast(IrPrint *irp, IrInstructionPtrCast *instruction) {
759 fprintf(irp->f, "@ptrcast(");
759 fprintf(irp->f, "@ptrCast(");
760760 if (instruction->dest_type) {
761761 ir_print_other_instruction(irp, instruction->dest_type);
762762 }
......@@ -765,6 +765,16 @@ static void ir_print_ptr_cast(IrPrint *irp, IrInstructionPtrCast *instruction) {
765765 fprintf(irp->f, ")");
766766}
767767
768static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) {
769 fprintf(irp->f, "@bitCast(");
770 if (instruction->dest_type) {
771 ir_print_other_instruction(irp, instruction->dest_type);
772 }
773 fprintf(irp->f, ",");
774 ir_print_other_instruction(irp, instruction->value);
775 fprintf(irp->f, ")");
776}
777
768778static void ir_print_widen_or_shorten(IrPrint *irp, IrInstructionWidenOrShorten *instruction) {
769779 fprintf(irp->f, "@widenOrShorten(");
770780 ir_print_other_instruction(irp, instruction->target);
......@@ -1124,6 +1134,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
11241134 case IrInstructionIdPtrCast:
11251135 ir_print_ptr_cast(irp, (IrInstructionPtrCast *)instruction);
11261136 break;
1137 case IrInstructionIdBitCast:
1138 ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction);
1139 break;
11271140 case IrInstructionIdWidenOrShorten:
11281141 ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction);
11291142 break;
std/build.zig+1-1
......@@ -11,7 +11,7 @@ const StdIo = os.ChildProcess.StdIo;
1111const Term = os.ChildProcess.Term;
1212const BufSet = @import("buf_set.zig").BufSet;
1313const BufMap = @import("buf_map.zig").BufMap;
14const fmt_lib = @import("fmt.zig");
14const fmt_lib = @import("fmt/index.zig");
1515
1616error ExtraArg;
1717error UncleanExit;
std/elf.zig+1-1
......@@ -1,5 +1,5 @@
11const io = @import("io.zig");
2const math = @import("math.zig");
2const math = @import("math/index.zig");
33const mem = @import("mem.zig");
44const debug = @import("debug.zig");
55
std/fmt.zig deleted-455
......@@ -1,455 +0,0 @@
1const math = @import("math.zig");
2const debug = @import("debug.zig");
3const assert = debug.assert;
4const mem = @import("mem.zig");
5const builtin = @import("builtin");
6
7const max_f64_digits = 65;
8const max_int_digits = 65;
9
10const State = enum { // TODO put inside format function and make sure the name and debug info is correct
11 Start,
12 OpenBrace,
13 CloseBrace,
14 Integer,
15 IntegerWidth,
16 Character,
17 Buf,
18 BufWidth,
19};
20
21/// Renders fmt string with args, calling output with slices of bytes.
22/// Return false from output function and output will not be called again.
23/// Returns false if output ever returned false, true otherwise.
24pub fn format(context: var, output: fn(@typeOf(context), []const u8)->bool,
25 comptime fmt: []const u8, args: ...) -> bool
26{
27 comptime var start_index = 0;
28 comptime var state = State.Start;
29 comptime var next_arg = 0;
30 comptime var radix = 0;
31 comptime var uppercase = false;
32 comptime var width = 0;
33 comptime var width_start = 0;
34
35 inline for (fmt) |c, i| {
36 switch (state) {
37 State.Start => switch (c) {
38 '{' => {
39 // TODO if you make this an if statement with `and` then it breaks
40 if (start_index < i) {
41 if (!output(context, fmt[start_index..i]))
42 return false;
43 }
44 state = State.OpenBrace;
45 },
46 '}' => {
47 if (start_index < i) {
48 if (!output(context, fmt[start_index..i]))
49 return false;
50 }
51 state = State.CloseBrace;
52 },
53 else => {},
54 },
55 State.OpenBrace => switch (c) {
56 '{' => {
57 state = State.Start;
58 start_index = i;
59 },
60 '}' => {
61 if (!formatValue(args[next_arg], context, output))
62 return false;
63 next_arg += 1;
64 state = State.Start;
65 start_index = i + 1;
66 },
67 'd' => {
68 radix = 10;
69 uppercase = false;
70 width = 0;
71 state = State.Integer;
72 },
73 'x' => {
74 radix = 16;
75 uppercase = false;
76 width = 0;
77 state = State.Integer;
78 },
79 'X' => {
80 radix = 16;
81 uppercase = true;
82 width = 0;
83 state = State.Integer;
84 },
85 'c' => {
86 state = State.Character;
87 },
88 's' => {
89 state = State.Buf;
90 },
91 else => @compileError("Unknown format character: " ++ []u8{c}),
92 },
93 State.Buf => switch (c) {
94 '}' => {
95 return output(context, args[next_arg]);
96 },
97 '0' ... '9' => {
98 width_start = i;
99 state = State.BufWidth;
100 },
101 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
102 },
103 State.CloseBrace => switch (c) {
104 '}' => {
105 state = State.Start;
106 start_index = i;
107 },
108 else => @compileError("Single '}' encountered in format string"),
109 },
110 State.Integer => switch (c) {
111 '}' => {
112 if (!formatInt(args[next_arg], radix, uppercase, width, context, output))
113 return false;
114 next_arg += 1;
115 state = State.Start;
116 start_index = i + 1;
117 },
118 '0' ... '9' => {
119 width_start = i;
120 state = State.IntegerWidth;
121 },
122 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
123 },
124 State.IntegerWidth => switch (c) {
125 '}' => {
126 width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
127 if (!formatInt(args[next_arg], radix, uppercase, width, context, output))
128 return false;
129 next_arg += 1;
130 state = State.Start;
131 start_index = i + 1;
132 },
133 '0' ... '9' => {},
134 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
135 },
136 State.BufWidth => switch (c) {
137 '}' => {
138 width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
139 if (!formatBuf(args[next_arg], width, context, output))
140 return false;
141 next_arg += 1;
142 state = State.Start;
143 start_index = i + 1;
144 },
145 '0' ... '9' => {},
146 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
147 },
148 State.Character => switch (c) {
149 '}' => {
150 if (!formatAsciiChar(args[next_arg], context, output))
151 return false;
152 next_arg += 1;
153 state = State.Start;
154 start_index = i + 1;
155 },
156 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
157 },
158 }
159 }
160 comptime {
161 if (args.len != next_arg) {
162 @compileError("Unused arguments");
163 }
164 if (state != State.Start) {
165 @compileError("Incomplete format string: " ++ fmt);
166 }
167 }
168 if (start_index < fmt.len) {
169 if (!output(context, fmt[start_index..]))
170 return false;
171 }
172
173 return true;
174}
175
176pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
177 const T = @typeOf(value);
178 switch (@typeId(T)) {
179 builtin.TypeId.Int => {
180 return formatInt(value, 10, false, 0, context, output);
181 },
182 builtin.TypeId.Float => {
183 @compileError("TODO implement formatFloat");
184 },
185 builtin.TypeId.Void => {
186 return output(context, "void");
187 },
188 builtin.TypeId.Bool => {
189 return output(context, if (value) "true" else "false");
190 },
191 builtin.TypeId.Nullable => {
192 if (value) |payload| {
193 return formatValue(payload, context, output);
194 } else {
195 return output(context, "null");
196 }
197 },
198 builtin.TypeId.ErrorUnion => {
199 if (value) |payload| {
200 return formatValue(payload, context, output);
201 } else |err| {
202 return formatValue(err, context, output);
203 }
204 },
205 builtin.TypeId.Error => {
206 if (!output(context, "error."))
207 return false;
208 return output(context, @errorName(value));
209 },
210 else => if (@canImplicitCast([]const u8, value)) {
211 const casted_value = ([]const u8)(value);
212 return output(context, casted_value);
213 } else {
214 @compileError("Unable to format type '" ++ @typeName(T) ++ "'");
215 },
216 }
217}
218
219pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
220 return output(context, (&c)[0..1]);
221}
222
223pub fn formatBuf(buf: []const u8, width: usize,
224 context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool
225{
226 if (!output(context, buf))
227 return false;
228
229 var leftover_padding = if (width > buf.len) (width - buf.len) else return true;
230 const pad_byte: u8 = ' ';
231 while (leftover_padding > 0) : (leftover_padding -= 1) {
232 if (!output(context, (&pad_byte)[0..1]))
233 return false;
234 }
235
236 return true;
237}
238
239
240pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
241 context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool
242{
243 if (@typeOf(value).is_signed) {
244 return formatIntSigned(value, base, uppercase, width, context, output);
245 } else {
246 return formatIntUnsigned(value, base, uppercase, width, context, output);
247 }
248}
249
250fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
251 context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool
252{
253 const uint = @IntType(false, @typeOf(value).bit_count);
254 if (value < 0) {
255 const minus_sign: u8 = '-';
256 if (!output(context, (&minus_sign)[0..1]))
257 return false;
258 const new_value = uint(-(value + 1)) + 1;
259 const new_width = if (width == 0) 0 else (width - 1);
260 return formatIntUnsigned(new_value, base, uppercase, new_width, context, output);
261 } else if (width == 0) {
262 return formatIntUnsigned(uint(value), base, uppercase, width, context, output);
263 } else {
264 const plus_sign: u8 = '+';
265 if (!output(context, (&plus_sign)[0..1]))
266 return false;
267 const new_value = uint(value);
268 const new_width = if (width == 0) 0 else (width - 1);
269 return formatIntUnsigned(new_value, base, uppercase, new_width, context, output);
270 }
271}
272
273fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
274 context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool
275{
276 // max_int_digits accounts for the minus sign. when printing an unsigned
277 // number we don't need to do that.
278 var buf: [max_int_digits - 1]u8 = undefined;
279 var a = value;
280 var index: usize = buf.len;
281
282 while (true) {
283 const digit = a % base;
284 index -= 1;
285 buf[index] = digitToChar(u8(digit), uppercase);
286 a /= base;
287 if (a == 0)
288 break;
289 }
290
291 const digits_buf = buf[index..];
292 const padding = if (width > digits_buf.len) (width - digits_buf.len) else 0;
293
294 if (padding > index) {
295 const zero_byte: u8 = '0';
296 var leftover_padding = padding - index;
297 while (true) {
298 if (!output(context, (&zero_byte)[0..1]))
299 return false;
300 leftover_padding -= 1;
301 if (leftover_padding == 0)
302 break;
303 }
304 mem.set(u8, buf[0..index], '0');
305 return output(context, buf);
306 } else {
307 const padded_buf = buf[index - padding..];
308 mem.set(u8, padded_buf[0..padding], '0');
309 return output(context, padded_buf);
310 }
311}
312
313pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width: usize) -> usize {
314 var context = FormatIntBuf {
315 .out_buf = out_buf,
316 .index = 0,
317 };
318 _ = formatInt(value, base, uppercase, width, &context, formatIntCallback);
319 return context.index;
320}
321const FormatIntBuf = struct {
322 out_buf: []u8,
323 index: usize,
324};
325fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) -> bool {
326 mem.copy(u8, context.out_buf[context.index..], bytes);
327 context.index += bytes.len;
328 return true;
329}
330
331pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {
332 var x: T = 0;
333
334 for (buf) |c| {
335 const digit = %return charToDigit(c, radix);
336 x = %return math.mul(T, x, radix);
337 x = %return math.add(T, x, digit);
338 }
339
340 return x;
341}
342
343error InvalidChar;
344fn charToDigit(c: u8, radix: u8) -> %u8 {
345 const value = switch (c) {
346 '0' ... '9' => c - '0',
347 'A' ... 'Z' => c - 'A' + 10,
348 'a' ... 'z' => c - 'a' + 10,
349 else => return error.InvalidChar,
350 };
351
352 if (value >= radix)
353 return error.InvalidChar;
354
355 return value;
356}
357
358fn digitToChar(digit: u8, uppercase: bool) -> u8 {
359 return switch (digit) {
360 0 ... 9 => digit + '0',
361 10 ... 35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),
362 else => unreachable,
363 };
364}
365
366const BufPrintContext = struct {
367 remaining: []u8,
368};
369
370fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> bool {
371 mem.copy(u8, context.remaining, bytes);
372 context.remaining = context.remaining[bytes.len..];
373 return true;
374}
375
376pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> []u8 {
377 var context = BufPrintContext { .remaining = buf, };
378 _ = format(&context, bufPrintWrite, fmt, args);
379 return buf[0..buf.len - context.remaining.len];
380}
381
382pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) -> %[]u8 {
383 var size: usize = 0;
384 _ = format(&size, countSize, fmt, args);
385 const buf = %return allocator.alloc(u8, size);
386 return bufPrint(buf, fmt, args);
387}
388
389fn countSize(size: &usize, bytes: []const u8) -> bool {
390 *size += bytes.len;
391 return true;
392}
393
394test "buf print int" {
395 var buffer: [max_int_digits]u8 = undefined;
396 const buf = buffer[0..];
397 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 2, false, 0), "-101111000110000101001110"));
398 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 10, false, 0), "-12345678"));
399 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, false, 0), "-bc614e"));
400 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, true, 0), "-BC614E"));
401
402 assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(12345678), 10, true, 0), "12345678"));
403
404 assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(666), 10, false, 6), "000666"));
405 assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, 6), "001234"));
406 assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, 1), "1234"));
407
408 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(42), 10, false, 3), "+42"));
409 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, 3), "-42"));
410}
411
412fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: usize) -> []u8 {
413 return buf[0..formatIntBuf(buf, value, base, uppercase, width)];
414}
415
416test "parse u64 digit too big" {
417 _ = parseUnsigned(u64, "123a", 10) %% |err| {
418 if (err == error.InvalidChar) return;
419 unreachable;
420 };
421 unreachable;
422}
423
424test "parse unsigned comptime" {
425 comptime {
426 assert(%%parseUnsigned(usize, "2", 10) == 2);
427 }
428}
429
430test "fmt.format" {
431 {
432 var buf1: [32]u8 = undefined;
433 const value: ?i32 = 1234;
434 const result = bufPrint(buf1[0..], "nullable: {}\n", value);
435 assert(mem.eql(u8, result, "nullable: 1234\n"));
436 }
437 {
438 var buf1: [32]u8 = undefined;
439 const value: ?i32 = null;
440 const result = bufPrint(buf1[0..], "nullable: {}\n", value);
441 assert(mem.eql(u8, result, "nullable: null\n"));
442 }
443 {
444 var buf1: [32]u8 = undefined;
445 const value: %i32 = 1234;
446 const result = bufPrint(buf1[0..], "error union: {}\n", value);
447 assert(mem.eql(u8, result, "error union: 1234\n"));
448 }
449 {
450 var buf1: [32]u8 = undefined;
451 const value: %i32 = error.InvalidChar;
452 const result = bufPrint(buf1[0..], "error union: {}\n", value);
453 assert(mem.eql(u8, result, "error union: error.InvalidChar\n"));
454 }
455}
std/fmt/errol/enum3.zig created+882
......@@ -0,0 +1,882 @@
1pub const enum3 = []u64 {
2 0x4e2e2785c3a2a20b,
3 0x240a28877a09a4e1,
4 0x728fca36c06cf106,
5 0x1016b100e18e5c17,
6 0x3159190e30e46c1d,
7 0x64312a13daa46fe4,
8 0x7c41926c7a7122ba,
9 0x08667a3c8dc4bc9c,
10 0x18dde996371c6060,
11 0x297c2c31a31998ae,
12 0x368b870de5d93270,
13 0x57d561def4a9ee32,
14 0x6d275d226331d03a,
15 0x76703d7cb98edc59,
16 0x7ec490abad057752,
17 0x037be9d5a60850b5,
18 0x0c63165633977bca,
19 0x14a048cb468bc209,
20 0x20dc29bc6879dfcd,
21 0x2643dc6227de9148,
22 0x2d64f14348a4c5db,
23 0x341eef5e1f90ac35,
24 0x4931159a8bd8a240,
25 0x503ca9bade45b94a,
26 0x5c1af5b5378aa2e5,
27 0x6b4ef9beaa7aa584,
28 0x6ef1c382c3819a0a,
29 0x754fe46e378bf133,
30 0x7ace779fddf21622,
31 0x7df22815078cb97b,
32 0x7f33c8eeb77b8d05,
33 0x011b7aa3d73f6658,
34 0x06ceb7f2c53db97f,
35 0x0b8f3d82e9356287,
36 0x0e304273b18918b0,
37 0x139fb24e492936f6,
38 0x176090684f5fe997,
39 0x1e3035e7b5183922,
40 0x220ce77c2b3328fc,
41 0x246441ed79830182,
42 0x279b5cd8bbdd8770,
43 0x2cc7c3fba45c1272,
44 0x3081eab25ad0fcf7,
45 0x329f5a18504dfaac,
46 0x347eef5e1f90ac35,
47 0x3a978cfcab31064c,
48 0x4baa32ac316fb3ab,
49 0x4eb9a2c2a34ac2f9,
50 0x522f6a5025e71a61,
51 0x5935ede8cce30845,
52 0x5f9aeac2d1ea2695,
53 0x6820ee7811241ad3,
54 0x6c06c9e14b7c22c3,
55 0x6e5a2fbffdb7580c,
56 0x71160cf8f38b0465,
57 0x738a37935f3b71c9,
58 0x756fe46e378bf133,
59 0x7856d2aa2fc5f2b5,
60 0x7bd3b063946e10ae,
61 0x7d8220e1772428d7,
62 0x7e222815078cb97b,
63 0x7ef5bc471d5456c7,
64 0x7fb82baa4ae611dc,
65 0x00bb7aa3d73f6658,
66 0x0190a0f3c55062c5,
67 0x05898e3445512a6e,
68 0x07bfe89cf1bd76ac,
69 0x08dfa7ebe304ee3e,
70 0x0c43165633977bca,
71 0x0e104273b18918b0,
72 0x0fd6ba8608faa6a9,
73 0x10b4139a6b17b224,
74 0x1466cc4fc92a0fa6,
75 0x162ba6008389068a,
76 0x1804116d591ef1fb,
77 0x1c513770474911bd,
78 0x1e7035e7b5183923,
79 0x2114dab846e19e25,
80 0x222ce77c2b3328fc,
81 0x244441ed79830182,
82 0x249b23b50fc204db,
83 0x278aacfcb88c92d6,
84 0x289d52af46e5fa6a,
85 0x2bdec922478c0421,
86 0x2d44f14348a4c5dc,
87 0x2f0c1249e96b6d8d,
88 0x30addc7e975c5045,
89 0x322aedaa0fc32ac8,
90 0x33deef5e1f90ac34,
91 0x343eef5e1f90ac35,
92 0x35ef1de1f7f14439,
93 0x3854faba79ea92ec,
94 0x47f52d02c7e14af7,
95 0x4a6bb6979ae39c49,
96 0x4c85564fb098c955,
97 0x4e80fde34c996086,
98 0x4ed9a2c2a34ac2f9,
99 0x51a3274280201a89,
100 0x574fe0403124a00e,
101 0x581561def4a9ee31,
102 0x5b55ed1f039cebff,
103 0x5e2780695036a679,
104 0x624be064a3fb2725,
105 0x674dcfee6690ffc6,
106 0x6a6cc08102f0da5b,
107 0x6be6c9e14b7c22c4,
108 0x6ce75d226331d03a,
109 0x6d5b9445072f4374,
110 0x6e927edd0dbb8c09,
111 0x71060cf8f38b0465,
112 0x71b1d7cb7eae05d9,
113 0x72fba10d818fdafd,
114 0x739a37935f3b71c9,
115 0x755fe46e378bf133,
116 0x76603d7cb98edc59,
117 0x78447e17e7814ce7,
118 0x799d696737fe68c7,
119 0x7ade779fddf21622,
120 0x7c1c283ffc61c87d,
121 0x7d1a85c6f7fba05d,
122 0x7da220e1772428d7,
123 0x7e022815078cb97b,
124 0x7e9a9b45a91f1700,
125 0x7ee3c8eeb77b8d05,
126 0x7f13c8eeb77b8d05,
127 0x7f6594223f5654bf,
128 0x7fd82baa4ae611dc,
129 0x002d243f646eaf51,
130 0x00f5d15b26b80e30,
131 0x0180a0f3c55062c5,
132 0x01f393b456eef178,
133 0x05798e3445512a6e,
134 0x06afdadafcacdf85,
135 0x06e8b03fd6894b66,
136 0x07cfe89cf1bd76ac,
137 0x08ac25584881552a,
138 0x097822507db6a8fd,
139 0x0c27b35936d56e28,
140 0x0c53165633977bca,
141 0x0c8e9eddbbb259b4,
142 0x0e204273b18918b0,
143 0x0f1d16d6d4b89689,
144 0x0fe6ba8608faa6a9,
145 0x105f48347c60a1be,
146 0x13627383c5456c5e,
147 0x13f93bb1e72a2033,
148 0x148048cb468bc208,
149 0x1514c0b3a63c1444,
150 0x175090684f5fe997,
151 0x17e4116d591ef1fb,
152 0x18cde996371c6060,
153 0x19aa2cf604c30d3f,
154 0x1d2b1ad9101b1bfd,
155 0x1e5035e7b5183923,
156 0x1fe5a79c4e71d028,
157 0x20ec29bc6879dfcd,
158 0x218ce77c2b3328fb,
159 0x221ce77c2b3328fc,
160 0x233f346f9ed36b89,
161 0x243441ed79830182,
162 0x245441ed79830182,
163 0x247441ed79830182,
164 0x2541e4ee41180c0a,
165 0x277aacfcb88c92d6,
166 0x279aacfcb88c92d6,
167 0x27cbb4c6bd8601bd,
168 0x28c04a616046e074,
169 0x2a4eeff57768f88c,
170 0x2c2379f099a86227,
171 0x2d04f14348a4c5db,
172 0x2d54f14348a4c5dc,
173 0x2d6a8c931c19b77a,
174 0x2fa387cf9cb4ad4e,
175 0x308ddc7e975c5046,
176 0x3149190e30e46c1d,
177 0x318d2ec75df6ba2a,
178 0x32548050091c3c24,
179 0x33beef5e1f90ac34,
180 0x33feef5e1f90ac35,
181 0x342eef5e1f90ac35,
182 0x345eef5e1f90ac35,
183 0x35108621c4199208,
184 0x366b870de5d93270,
185 0x375b20c2f4f8d4a0,
186 0x3864faba79ea92ec,
187 0x3aa78cfcab31064c,
188 0x4919d9577de925d5,
189 0x49ccadd6dd730c96,
190 0x4b9a32ac316fb3ab,
191 0x4bba32ac316fb3ab,
192 0x4cff20b1a0d7f626,
193 0x4e3e2785c3a2a20b,
194 0x4ea9a2c2a34ac2f9,
195 0x4ec9a2c2a34ac2f9,
196 0x4f28750ea732fdae,
197 0x513843e10734fa57,
198 0x51e71760b3c0bc13,
199 0x55693ba3249a8511,
200 0x57763ae2caed4528,
201 0x57f561def4a9ee32,
202 0x584561def4a9ee31,
203 0x5b45ed1f039cebfe,
204 0x5bfaf5b5378aa2e5,
205 0x5c6cf45d333da323,
206 0x5e64ec8fd70420c7,
207 0x6009813653f62db7,
208 0x64112a13daa46fe4,
209 0x672dcfee6690ffc6,
210 0x677a77581053543b,
211 0x699873e3758bc6b3,
212 0x6b3ef9beaa7aa584,
213 0x6b7b86d8c3df7cd1,
214 0x6bf6c9e14b7c22c3,
215 0x6c16c9e14b7c22c3,
216 0x6d075d226331d03a,
217 0x6d5a3bdac4f00f33,
218 0x6e4a2fbffdb7580c,
219 0x6e927edd0dbb8c08,
220 0x6ee1c382c3819a0a,
221 0x70f60cf8f38b0465,
222 0x7114390c68b888ce,
223 0x714fb4840532a9e5,
224 0x727fca36c06cf106,
225 0x72eba10d818fdafd,
226 0x737a37935f3b71c9,
227 0x73972852443155ae,
228 0x754fe46e378bf132,
229 0x755fe46e378bf132,
230 0x756fe46e378bf132,
231 0x76603d7cb98edc58,
232 0x76703d7cb98edc58,
233 0x782f7c6a9ad432a1,
234 0x78547e17e7814ce7,
235 0x7964066d88c7cab8,
236 0x7ace779fddf21621,
237 0x7ade779fddf21621,
238 0x7bc3b063946e10ae,
239 0x7c0c283ffc61c87d,
240 0x7c31926c7a7122ba,
241 0x7d0a85c6f7fba05d,
242 0x7d52a5daf9226f04,
243 0x7d9220e1772428d7,
244 0x7db220e1772428d7,
245 0x7dfe5aceedf1c1f1,
246 0x7e122815078cb97b,
247 0x7e8a9b45a91f1700,
248 0x7eb6202598194bee,
249 0x7ec6202598194bee,
250 0x7ef3c8eeb77b8d05,
251 0x7f03c8eeb77b8d05,
252 0x7f23c8eeb77b8d05,
253 0x7f5594223f5654bf,
254 0x7f9914e03c9260ee,
255 0x7fc82baa4ae611dc,
256 0x7fefffffffffffff,
257 0x001d243f646eaf51,
258 0x00ab7aa3d73f6658,
259 0x00cb7aa3d73f6658,
260 0x010b7aa3d73f6658,
261 0x012b7aa3d73f6658,
262 0x0180a0f3c55062c6,
263 0x0190a0f3c55062c6,
264 0x03719f08ccdccfe5,
265 0x03dc25ba6a45de02,
266 0x05798e3445512a6f,
267 0x05898e3445512a6f,
268 0x06bfdadafcacdf85,
269 0x06cfdadafcacdf85,
270 0x06f8b03fd6894b66,
271 0x07c1707c02068785,
272 0x08567a3c8dc4bc9c,
273 0x089c25584881552a,
274 0x08dfa7ebe304ee3d,
275 0x096822507db6a8fd,
276 0x09e41934d77659be,
277 0x0c27b35936d56e27,
278 0x0c43165633977bc9,
279 0x0c53165633977bc9,
280 0x0c63165633977bc9,
281 0x0c7e9eddbbb259b4,
282 0x0c9e9eddbbb259b4,
283 0x0e104273b18918b1,
284 0x0e204273b18918b1,
285 0x0e304273b18918b1,
286 0x0fd6ba8608faa6a8,
287 0x0fe6ba8608faa6a8,
288 0x1006b100e18e5c17,
289 0x104f48347c60a1be,
290 0x10a4139a6b17b224,
291 0x12cb91d317c8ebe9,
292 0x138fb24e492936f6,
293 0x13afb24e492936f6,
294 0x14093bb1e72a2033,
295 0x1476cc4fc92a0fa6,
296 0x149048cb468bc209,
297 0x1504c0b3a63c1444,
298 0x161ba6008389068a,
299 0x168cfab1a09b49c4,
300 0x175090684f5fe998,
301 0x176090684f5fe998,
302 0x17f4116d591ef1fb,
303 0x18a710b7a2ef18b7,
304 0x18d99fccca44882a,
305 0x199a2cf604c30d3f,
306 0x1b5ebddc6593c857,
307 0x1d1b1ad9101b1bfd,
308 0x1d3b1ad9101b1bfd,
309 0x1e4035e7b5183923,
310 0x1e6035e7b5183923,
311 0x1fd5a79c4e71d028,
312 0x20cc29bc6879dfcd,
313 0x20e8823a57adbef8,
314 0x2104dab846e19e25,
315 0x2124dab846e19e25,
316 0x220ce77c2b3328fb,
317 0x221ce77c2b3328fb,
318 0x222ce77c2b3328fb,
319 0x229197b290631476,
320 0x240a28877a09a4e0,
321 0x243441ed79830181,
322 0x244441ed79830181,
323 0x245441ed79830181,
324 0x246441ed79830181,
325 0x247441ed79830181,
326 0x248b23b50fc204db,
327 0x24ab23b50fc204db,
328 0x2633dc6227de9148,
329 0x2653dc6227de9148,
330 0x277aacfcb88c92d7,
331 0x278aacfcb88c92d7,
332 0x279aacfcb88c92d7,
333 0x27bbb4c6bd8601bd,
334 0x289d52af46e5fa69,
335 0x28b04a616046e074,
336 0x28d04a616046e074,
337 0x2a3eeff57768f88c,
338 0x2b8e3a0aeed7be19,
339 0x2beec922478c0421,
340 0x2cc7c3fba45c1271,
341 0x2cf4f14348a4c5db,
342 0x2d44f14348a4c5db,
343 0x2d54f14348a4c5db,
344 0x2d5a8c931c19b77a,
345 0x2d64f14348a4c5dc,
346 0x2efc1249e96b6d8d,
347 0x2f0f6b23cfe98807,
348 0x2fe91b9de4d5cf31,
349 0x308ddc7e975c5045,
350 0x309ddc7e975c5045,
351 0x30bddc7e975c5045,
352 0x3150ed9bd6bfd003,
353 0x317d2ec75df6ba2a,
354 0x321aedaa0fc32ac8,
355 0x32448050091c3c24,
356 0x328f5a18504dfaac,
357 0x3336dca59d035820,
358 0x33ceef5e1f90ac34,
359 0x33eeef5e1f90ac35,
360 0x340eef5e1f90ac35,
361 0x34228f9edfbd3420,
362 0x34328f9edfbd3420,
363 0x344eef5e1f90ac35,
364 0x346eef5e1f90ac35,
365 0x35008621c4199208,
366 0x35e0ac2e7f90b8a3,
367 0x361dde4a4ab13e09,
368 0x367b870de5d93270,
369 0x375b20c2f4f8d49f,
370 0x37f25d342b1e33e5,
371 0x3854faba79ea92ed,
372 0x3864faba79ea92ed,
373 0x3a978cfcab31064d,
374 0x3aa78cfcab31064d,
375 0x490cd230a7ff47c3,
376 0x4929d9577de925d5,
377 0x4939d9577de925d5,
378 0x49dcadd6dd730c96,
379 0x4a7bb6979ae39c49,
380 0x4b9a32ac316fb3ac,
381 0x4baa32ac316fb3ac,
382 0x4bba32ac316fb3ac,
383 0x4cef20b1a0d7f626,
384 0x4e2e2785c3a2a20a,
385 0x4e3e2785c3a2a20a,
386 0x4e6454b1aef62c8d,
387 0x4e90fde34c996086,
388 0x4ea9a2c2a34ac2fa,
389 0x4eb9a2c2a34ac2fa,
390 0x4ec9a2c2a34ac2fa,
391 0x4ed9a2c2a34ac2fa,
392 0x4f38750ea732fdae,
393 0x504ca9bade45b94a,
394 0x514843e10734fa57,
395 0x51b3274280201a89,
396 0x521f6a5025e71a61,
397 0x52c6a47d4e7ec633,
398 0x55793ba3249a8511,
399 0x575fe0403124a00e,
400 0x57863ae2caed4528,
401 0x57e561def4a9ee32,
402 0x580561def4a9ee31,
403 0x582561def4a9ee31,
404 0x585561def4a9ee31,
405 0x59d0dd8f2788d699,
406 0x5b55ed1f039cebfe,
407 0x5beaf5b5378aa2e5,
408 0x5c0af5b5378aa2e5,
409 0x5c4ef3052ef0a361,
410 0x5e1780695036a679,
411 0x5e54ec8fd70420c7,
412 0x5e6b5e2f86026f05,
413 0x5faaeac2d1ea2695,
414 0x611260322d04d50b,
415 0x625be064a3fb2725,
416 0x64212a13daa46fe4,
417 0x671dcfee6690ffc6,
418 0x673dcfee6690ffc6,
419 0x675dcfee6690ffc6,
420 0x678a77581053543b,
421 0x682d3683fa3d1ee0,
422 0x699cb490951e8515,
423 0x6b3ef9beaa7aa583,
424 0x6b4ef9beaa7aa583,
425 0x6b7896beb0c66eb9,
426 0x6bdf20938e7414bb,
427 0x6bef20938e7414bb,
428 0x6bf6c9e14b7c22c4,
429 0x6c06c9e14b7c22c4,
430 0x6c16c9e14b7c22c4,
431 0x6cf75d226331d03a,
432 0x6d175d226331d03a,
433 0x6d4b9445072f4374,
434};
435
436const Slab = struct {
437 str: []const u8,
438 exp: i32,
439};
440
441fn slab(str: []const u8, exp: i32) -> Slab {
442 Slab {
443 .str = str,
444 .exp = exp,
445 }
446}
447
448pub const enum3_data = []Slab {
449 slab("40648030339495312", 69),
450 slab("4498645355592131", -134),
451 slab("678321594594593", 244),
452 slab("36539702510912277", -230),
453 slab("56819570380646536", -70),
454 slab("42452693975546964", 175),
455 slab("34248868699178663", 291),
456 slab("34037810581283983", -267),
457 slab("67135881167178176", -188),
458 slab("74973710847373845", -108),
459 slab("60272377639347644", -45),
460 slab("1316415380484425", 116),
461 slab("64433314612521525", 218),
462 slab("31961502891542243", 263),
463 slab("4407140524515149", 303),
464 slab("69928982131052126", -291),
465 slab("5331838923808276", -248),
466 slab("24766435002945523", -208),
467 slab("21509066976048781", -149),
468 slab("2347200170470694", -123),
469 slab("51404180294474556", -89),
470 slab("12320586499023201", -56),
471 slab("38099461575161174", 45),
472 slab("3318949537676913", 79),
473 slab("48988560059074597", 136),
474 slab("7955843973866726", 209),
475 slab("2630089515909384", 227),
476 slab("11971601492124911", 258),
477 slab("35394816534699092", 284),
478 slab("47497368114750945", 299),
479 slab("54271187548763685", 305),
480 slab("2504414972009504", -302),
481 slab("69316187906522606", -275),
482 slab("53263359599109627", -252),
483 slab("24384437085962037", -239),
484 slab("3677854139813342", -213),
485 slab("44318030915155535", -195),
486 slab("28150140033551147", -162),
487 slab("1157373742186464", -143),
488 slab("2229658838863212", -132),
489 slab("67817280930489786", -117),
490 slab("56966478488538934", -92),
491 slab("49514357246452655", -74),
492 slab("74426102121433776", -64),
493 slab("78851753593748485", -55),
494 slab("19024128529074359", -25),
495 slab("32118580932839778", 57),
496 slab("17693166778887419", 72),
497 slab("78117757194253536", 88),
498 slab("56627018760181905", 122),
499 slab("35243988108650928", 153),
500 slab("38624526316654214", 194),
501 slab("2397422026462446", 213),
502 slab("37862966954556723", 224),
503 slab("56089100059334965", 237),
504 slab("3666156212014994", 249),
505 slab("47886405968499643", 258),
506 slab("48228872759189434", 272),
507 slab("29980574575739863", 289),
508 slab("37049827284413546", 297),
509 slab("37997894491800756", 300),
510 slab("37263572163337027", 304),
511 slab("16973149506391291", 308),
512 slab("391314839376485", -304),
513 slab("38797447671091856", -300),
514 slab("54994366114768736", -281),
515 slab("23593494977819109", -270),
516 slab("61359116592542813", -265),
517 slab("1332959730952069", -248),
518 slab("6096109271490509", -240),
519 slab("22874741188249992", -231),
520 slab("33104948806015703", -227),
521 slab("21670630627577332", -209),
522 slab("70547825868713855", -201),
523 slab("54981742371928845", -192),
524 slab("27843818440071113", -171),
525 slab("4504022405368184", -161),
526 slab("2548351460621656", -148),
527 slab("4629494968745856", -143),
528 slab("557414709715803", -133),
529 slab("23897004381644022", -131),
530 slab("33057350728075958", -117),
531 slab("47628822744182433", -112),
532 slab("22520091703825729", -96),
533 slab("1285104507361864", -89),
534 slab("46239793787746783", -81),
535 slab("330095714976351", -73),
536 slab("4994144928421182", -66),
537 slab("77003665618895", -58),
538 slab("49282345996092803", -56),
539 slab("66534156679273626", -48),
540 slab("24661175471861008", -36),
541 slab("45035996273704964", 39),
542 slab("32402369146794532", 51),
543 slab("42859354584576066", 61),
544 slab("1465909318208761", 71),
545 slab("70772667115549675", 72),
546 slab("18604316837693468", 86),
547 slab("38329392744333992", 113),
548 slab("21062646087750798", 117),
549 slab("972708181182949", 132),
550 slab("36683053719290777", 146),
551 slab("32106017483029628", 166),
552 slab("41508952543121158", 190),
553 slab("45072812455233127", 205),
554 slab("59935550661561155", 212),
555 slab("40270821632825953", 217),
556 slab("60846862848160256", 219),
557 slab("42788225889846894", 225),
558 slab("28044550029667482", 237),
559 slab("46475406389115295", 240),
560 slab("7546114860200514", 246),
561 slab("7332312424029988", 249),
562 slab("23943202984249821", 258),
563 slab("15980751445771122", 263),
564 slab("21652206566352648", 272),
565 slab("65171333649148234", 278),
566 slab("70789633069398184", 284),
567 slab("68600253110025576", 290),
568 slab("4234784709771466", 295),
569 slab("14819930913765419", 298),
570 slab("9499473622950189", 299),
571 slab("71272819274635585", 302),
572 slab("16959746108988652", 304),
573 slab("13567796887190921", 305),
574 slab("4735325513114182", 306),
575 slab("67892598025565165", 308),
576 slab("81052743999542975", -307),
577 slab("4971131903427841", -303),
578 slab("19398723835545928", -300),
579 slab("29232758945460627", -298),
580 slab("27497183057384368", -281),
581 slab("17970091719480621", -275),
582 slab("22283747288943228", -274),
583 slab("47186989955638217", -270),
584 slab("6819439187504402", -266),
585 slab("47902021250710456", -262),
586 slab("41378294570975613", -249),
587 slab("2665919461904138", -248),
588 slab("3421423777071132", -247),
589 slab("12192218542981019", -239),
590 slab("7147520638007367", -235),
591 slab("45749482376499984", -231),
592 slab("80596937390013985", -229),
593 slab("26761990828289327", -214),
594 slab("18738512510673039", -211),
595 slab("619160875073638", -209),
596 slab("403997300048931", -206),
597 slab("22159015457577768", -195),
598 slab("13745435592982211", -192),
599 slab("33567940583589088", -188),
600 slab("4812711195250522", -184),
601 slab("3591036630219558", -167),
602 slab("1126005601342046", -161),
603 slab("5047135806497922", -154),
604 slab("43018133952097563", -149),
605 slab("45209911804158747", -146),
606 slab("2314747484372928", -143),
607 slab("65509428048152994", -138),
608 slab("2787073548579015", -133),
609 slab("1114829419431606", -132),
610 slab("4459317677726424", -132),
611 slab("32269008655522087", -128),
612 slab("16528675364037979", -117),
613 slab("66114701456151916", -117),
614 slab("54934856534126976", -116),
615 slab("21168365664081082", -111),
616 slab("67445733463759384", -104),
617 slab("45590931008842566", -95),
618 slab("8031903171011649", -91),
619 slab("2570209014723728", -89),
620 slab("6516605505584466", -89),
621 slab("32943123175907307", -78),
622 slab("82523928744087755", -74),
623 slab("28409785190323268", -70),
624 slab("52853886779813977", -69),
625 slab("30417302377115577", -65),
626 slab("1925091640472375", -58),
627 slab("30801466247558002", -57),
628 slab("24641172998046401", -56),
629 slab("19712938398437121", -55),
630 slab("43129529027318865", -52),
631 slab("15068094409836911", -45),
632 slab("48658418478920193", -41),
633 slab("49322350943722016", -36),
634 slab("38048257058148717", -25),
635 slab("14411294198511291", 45),
636 slab("32745697577386472", 48),
637 slab("16059290466419889", 57),
638 slab("64237161865679556", 57),
639 slab("8003248329710242", 63),
640 slab("81296060678990625", 69),
641 slab("8846583389443709", 71),
642 slab("35386333557774838", 72),
643 slab("21606114462319112", 74),
644 slab("18413733104063271", 84),
645 slab("35887030159858487", 87),
646 slab("2825769263311679", 104),
647 slab("2138446062528161", 114),
648 slab("52656615219377", 116),
649 slab("16850116870200639", 118),
650 slab("48635409059147446", 132),
651 slab("12247140014768649", 136),
652 slab("16836228873919609", 138),
653 slab("5225574770881846", 147),
654 slab("42745323906998127", 155),
655 slab("10613173493886741", 175),
656 slab("10377238135780289", 190),
657 slab("29480080280199528", 191),
658 slab("4679330956996797", 201),
659 slab("3977921986933363", 209),
660 slab("56560320317673966", 210),
661 slab("1198711013231223", 213),
662 slab("4794844052924892", 213),
663 slab("16108328653130381", 218),
664 slab("57878622568856074", 219),
665 slab("18931483477278361", 224),
666 slab("4278822588984689", 225),
667 slab("1315044757954692", 227),
668 slab("14022275014833741", 237),
669 slab("5143975308105889", 237),
670 slab("64517311884236306", 238),
671 slab("3391607972972965", 244),
672 slab("3773057430100257", 246),
673 slab("1833078106007497", 249),
674 slab("64766168833734675", 249),
675 slab("1197160149212491", 258),
676 slab("2394320298424982", 258),
677 slab("4788640596849964", 258),
678 slab("1598075144577112", 263),
679 slab("3196150289154224", 263),
680 slab("83169412421960475", 271),
681 slab("43304413132705296", 272),
682 slab("5546524276967009", 277),
683 slab("3539481653469909", 284),
684 slab("7078963306939818", 284),
685 slab("14990287287869931", 289),
686 slab("34300126555012788", 290),
687 slab("17124434349589332", 291),
688 slab("2117392354885733", 295),
689 slab("47639264836707725", 296),
690 slab("7409965456882709", 297),
691 slab("29639861827530837", 298),
692 slab("79407577493590275", 299),
693 slab("18998947245900378", 300),
694 slab("35636409637317792", 302),
695 slab("23707742595255608", 303),
696 slab("47415485190511216", 303),
697 slab("33919492217977303", 304),
698 slab("6783898443595461", 304),
699 slab("27135593774381842", 305),
700 slab("2367662756557091", 306),
701 slab("44032152438472327", 307),
702 slab("33946299012782582", 308),
703 slab("17976931348623157", 309),
704 slab("40526371999771488", -307),
705 slab("1956574196882425", -304),
706 slab("78262967875297", -304),
707 slab("1252207486004752", -302),
708 slab("5008829944019008", -302),
709 slab("1939872383554593", -300),
710 slab("3879744767109186", -300),
711 slab("44144884605471774", -291),
712 slab("45129663866844427", -289),
713 slab("2749718305738437", -281),
714 slab("5499436611476874", -281),
715 slab("35940183438961242", -275),
716 slab("71880366877922484", -275),
717 slab("44567494577886457", -274),
718 slab("25789638850173173", -270),
719 slab("17018905290641991", -267),
720 slab("3409719593752201", -266),
721 slab("6135911659254281", -265),
722 slab("23951010625355228", -262),
723 slab("51061856989121905", -260),
724 slab("4137829457097561", -249),
725 slab("13329597309520689", -248),
726 slab("26659194619041378", -248),
727 slab("53318389238082755", -248),
728 slab("1710711888535566", -247),
729 slab("6842847554142264", -247),
730 slab("609610927149051", -240),
731 slab("1219221854298102", -239),
732 slab("2438443708596204", -239),
733 slab("2287474118824999", -231),
734 slab("4574948237649998", -231),
735 slab("18269851255456139", -230),
736 slab("40298468695006992", -229),
737 slab("16552474403007851", -227),
738 slab("39050270537318193", -217),
739 slab("1838927069906671", -213),
740 slab("7355708279626684", -213),
741 slab("37477025021346077", -211),
742 slab("43341261255154663", -209),
743 slab("12383217501472761", -208),
744 slab("2019986500244655", -206),
745 slab("35273912934356928", -201),
746 slab("47323883490786093", -199),
747 slab("2215901545757777", -195),
748 slab("4431803091515554", -195),
749 slab("27490871185964422", -192),
750 slab("64710073234908765", -189),
751 slab("57511323531737074", -188),
752 slab("2406355597625261", -184),
753 slab("75862936714499446", -176),
754 slab("1795518315109779", -167),
755 slab("7182073260439116", -167),
756 slab("563002800671023", -162),
757 slab("2252011202684092", -161),
758 slab("2523567903248961", -154),
759 slab("10754533488024391", -149),
760 slab("37436263604934127", -149),
761 slab("1274175730310828", -148),
762 slab("5096702921243312", -148),
763 slab("11573737421864639", -143),
764 slab("23147474843729279", -143),
765 slab("46294949687458557", -143),
766 slab("36067106647774144", -141),
767 slab("44986453555921307", -134),
768 slab("27870735485790148", -133),
769 slab("55741470971580295", -133),
770 slab("11148294194316059", -132),
771 slab("22296588388632118", -132),
772 slab("44593176777264236", -132),
773 slab("11948502190822011", -131),
774 slab("47794008763288043", -131),
775 slab("1173600085235347", -123),
776 slab("4694400340941388", -123),
777 slab("1652867536403798", -117),
778 slab("3305735072807596", -117),
779 slab("6611470145615192", -117),
780 slab("27467428267063488", -116),
781 slab("4762882274418243", -112),
782 slab("10584182832040541", -111),
783 slab("42336731328162165", -111),
784 slab("33722866731879692", -104),
785 slab("69097540994131414", -98),
786 slab("45040183407651457", -96),
787 slab("5696647848853893", -92),
788 slab("40159515855058247", -91),
789 slab("12851045073618639", -89),
790 slab("25702090147237278", -89),
791 slab("3258302752792233", -89),
792 slab("5140418029447456", -89),
793 slab("23119896893873391", -81),
794 slab("51753157237874753", -81),
795 slab("67761208324172855", -77),
796 slab("8252392874408775", -74),
797 slab("1650478574881755", -73),
798 slab("660191429952702", -73),
799 slab("3832399419240467", -70),
800 slab("26426943389906988", -69),
801 slab("2497072464210591", -66),
802 slab("15208651188557789", -65),
803 slab("37213051060716888", -64),
804 slab("55574205388093594", -61),
805 slab("385018328094475", -58),
806 slab("15400733123779001", -57),
807 slab("61602932495116004", -57),
808 slab("14784703798827841", -56),
809 slab("29569407597655683", -56),
810 slab("9856469199218561", -56),
811 slab("39425876796874242", -55),
812 slab("21564764513659432", -52),
813 slab("35649516398744314", -48),
814 slab("51091836539008967", -47),
815 slab("30136188819673822", -45),
816 slab("4865841847892019", -41),
817 slab("33729482964455627", -38),
818 slab("2466117547186101", -36),
819 slab("4932235094372202", -36),
820 slab("1902412852907436", -25),
821 slab("3804825705814872", -25),
822 slab("80341375308088225", 44),
823 slab("28822588397022582", 45),
824 slab("57645176794045164", 45),
825 slab("65491395154772944", 48),
826 slab("64804738293589064", 51),
827 slab("1605929046641989", 57),
828 slab("3211858093283978", 57),
829 slab("6423716186567956", 57),
830 slab("4001624164855121", 63),
831 slab("4064803033949531", 69),
832 slab("8129606067899062", 69),
833 slab("4384946084578497", 70),
834 slab("2931818636417522", 71),
835 slab("884658338944371", 71),
836 slab("1769316677888742", 72),
837 slab("3538633355777484", 72),
838 slab("7077266711554968", 72),
839 slab("43212228924638223", 74),
840 slab("6637899075353826", 79),
841 slab("36827466208126543", 84),
842 slab("37208633675386937", 86),
843 slab("39058878597126768", 88),
844 slab("57654578150150385", 91),
845 slab("5651538526623358", 104),
846 slab("76658785488667984", 113),
847 slab("4276892125056322", 114),
848 slab("263283076096885", 116),
849 slab("10531323043875399", 117),
850 slab("42125292175501597", 117),
851 slab("33700233740401277", 118),
852 slab("44596066840334405", 125),
853 slab("9727081811829489", 132),
854 slab("61235700073843246", 135),
855 slab("24494280029537298", 136),
856 slab("4499029632233837", 137),
857 slab("18341526859645389", 146),
858 slab("2612787385440923", 147),
859 slab("6834859331393543", 147),
860 slab("70487976217301855", 153),
861 slab("40366692112133834", 160),
862 slab("64212034966059256", 166),
863 slab("21226346987773482", 175),
864 slab("51886190678901447", 189),
865 slab("20754476271560579", 190),
866 slab("83017905086242315", 190),
867 slab("58960160560399056", 191),
868 slab("66641177824100826", 194),
869 slab("5493127645170153", 201),
870 slab("39779219869333628", 209),
871 slab("79558439738667255", 209),
872 slab("50523702331566894", 210),
873 slab("40933393326155808", 212),
874 slab("81866786652311615", 212),
875 slab("11987110132312231", 213),
876 slab("23974220264624462", 213),
877 slab("47948440529248924", 213),
878 slab("8054164326565191", 217),
879 slab("32216657306260762", 218),
880 slab("30423431424080128", 219),
881};
882
std/fmt/errol/index.zig created+651
......@@ -0,0 +1,651 @@
1const enum3 = @import("enum3.zig").enum3;
2const enum3_data = @import("enum3.zig").enum3_data;
3const lookup_table = @import("lookup.zig").lookup_table;
4const HP = @import("lookup.zig").HP;
5const math = @import("../../math/index.zig");
6const mem = @import("../../mem.zig");
7const assert = @import("../../debug.zig").assert;
8
9pub const FloatDecimal = struct {
10 digits: []u8,
11 exp: i32,
12};
13
14const u128 = @IntType(false, 128);
15
16/// Corrected Errol3 double to ASCII conversion.
17pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
18 const bits = @bitCast(u64, value);
19 const i = tableLowerBound(bits);
20 if (i < enum3.len and enum3[i] == bits) {
21 const data = enum3_data[i];
22 const digits = buffer[0..data.str.len];
23 mem.copy(u8, digits, data.str);
24 return FloatDecimal {
25 .digits = digits,
26 .exp = data.exp,
27 };
28 }
29
30 return errol3u(value, buffer);
31}
32
33/// Uncorrected Errol3 double to ASCII conversion.
34fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
35 // check if in integer or fixed range
36
37 if (val >= 9.007199254740992e15 and val < 3.40282366920938e+38) {
38 return errolInt(val, buffer);
39 } else if (val >= 16.0 and val < 9.007199254740992e15) {
40 return errolFixed(val, buffer);
41 }
42
43
44 // normalize the midpoint
45
46 var e: i32 = undefined;
47 _ = math.frexp(val, &e);
48 var exp = i16(math.floor(307 + f64(e) * 0.30103));
49 if (exp < 20) {
50 exp = 20;
51 } else if (usize(exp) >= lookup_table.len) {
52 exp = i16(lookup_table.len - 1);
53 }
54
55 var mid = lookup_table[usize(exp)];
56 mid = hpProd(mid, val);
57 const lten = lookup_table[usize(exp)].val;
58
59 exp -= 307;
60
61 var ten: f64 = 1.0;
62
63 while (mid.val > 10.0 or (mid.val == 10.0 and mid.off >= 0.0)) {
64 exp += 1;
65 hpDiv10(&mid);
66 ten /= 10.0;
67 }
68
69 while (mid.val < 1.0 or (mid.val == 1.0 and mid.off < 0.0)) {
70 exp -= 1;
71 hpMul10(&mid);
72 ten *= 10.0;
73 }
74
75 // compute boundaries
76 var high = HP {
77 .val = mid.val,
78 .off = mid.off + (fpnext(val) - val) * lten * ten / 2.0,
79 };
80 var low = HP {
81 .val = mid.val,
82 .off = mid.off + (fpprev(val) - val) * lten * ten / 2.0,
83 };
84
85 hpNormalize(&high);
86 hpNormalize(&low);
87
88 // normalized boundaries
89
90 while (high.val > 10.0 or (high.val == 10.0 and high.off >= 0.0)) {
91 exp += 1;
92 hpDiv10(&high);
93 hpDiv10(&low);
94 }
95
96 while (high.val < 1.0 or (high.val == 1.0 and high.off < 0.0)) {
97 exp -= 1;
98 hpMul10(&high);
99 hpMul10(&low);
100 }
101
102 // digit generation
103 var buf_index: usize = 0;
104 while (true) {
105 var hdig = u8(math.floor(high.val));
106 if ((high.val == f64(hdig)) and (high.off < 0))
107 hdig -= 1;
108
109 var ldig = u8(math.floor(low.val));
110 if ((low.val == f64(ldig)) and (low.off < 0))
111 ldig -= 1;
112
113 if (ldig != hdig)
114 break;
115
116 buffer[buf_index] = hdig + '0';
117 buf_index += 1;
118 high.val -= f64(hdig);
119 low.val -= f64(ldig);
120 hpMul10(&high);
121 hpMul10(&low);
122 }
123
124 const tmp = (high.val + low.val) / 2.0;
125 var mdig = u8(math.floor(tmp + 0.5));
126 if ((f64(mdig) - tmp) == 0.5 and (mdig & 0x1) != 0)
127 mdig -= 1;
128
129 buffer[buf_index] = mdig + '0';
130 buf_index += 1;
131
132 return FloatDecimal {
133 .digits = buffer[0..buf_index],
134 .exp = exp,
135 };
136}
137
138fn tableLowerBound(k: u64) -> usize {
139 var i = enum3.len;
140 var j: usize = 0;
141
142 while (j < enum3.len) {
143 if (enum3[j] < k) {
144 j = 2 * k + 2;
145 } else {
146 i = j;
147 j = 2 * j + 1;
148 }
149 }
150
151 return i;
152}
153
154/// Compute the product of an HP number and a double.
155/// @in: The HP number.
156/// @val: The double.
157/// &returns: The HP number.
158fn hpProd(in: &const HP, val: f64) -> HP {
159 var hi: f64 = undefined;
160 var lo: f64 = undefined;
161 split(in.val, &hi, &lo);
162
163 var hi2: f64 = undefined;
164 var lo2: f64 = undefined;
165 split(val, &hi2, &lo2);
166
167 const p = in.val * val;
168 const e = ((hi * hi2 - p) + lo * hi2 + hi * lo2) + lo * lo2;
169
170 return HP {
171 .val = p,
172 .off = in.off * val + e,
173 };
174}
175
176/// Split a double into two halves.
177/// @val: The double.
178/// @hi: The high bits.
179/// @lo: The low bits.
180fn split(val: f64, hi: &f64, lo: &f64) {
181 *hi = gethi(val);
182 *lo = val - *hi;
183}
184
185fn gethi(in: f64) {
186 const bits = @bitCast(u64, in);
187 const new_bits = bits & 0xFFFFFFFFF8000000;
188 return @bitCast(f64, new_bits);
189}
190
191/// Normalize the number by factoring in the error.
192/// @hp: The float pair.
193fn hpNormalize(hp: &HP) {
194 const val = hp.val;
195
196 hp.val += hp.off;
197 hp.off += val - hp.val;
198}
199
200/// Divide the high-precision number by ten.
201/// @hp: The high-precision number
202fn hpDiv10(hp: &HP) {
203 const val = hp.val;
204
205 hp.val /= 10.0;
206 hp.off /= 10.0;
207
208 val -= hp.val * 8.0;
209 val -= hp.val * 2.0;
210
211 hp.off += val / 10.0;
212
213 hpNormalize(hp);
214}
215
216/// Multiply the high-precision number by ten.
217/// @hp: The high-precision number
218fn hpMul10(hp: &HP) {
219 const val = hp.val;
220
221 hp.val *= 10.0;
222 hp.off *= 10.0;
223
224 var off = hp.val;
225 off -= val * 8.0;
226 off -= val * 2.0;
227
228 hp.off -= off;
229
230 hpNormalize(hp);
231}
232
233
234/// Integer conversion algorithm, guaranteed correct, optimal, and best.
235/// @val: The val.
236/// @buf: The output buffer.
237/// &return: The exponent.
238fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
239 const pow19 = 1e19;
240
241 assert((val >= 9.007199254740992e15) and val < (3.40282366920938e38));
242
243 var mid = u128(val);
244 var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0);
245 var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0);
246
247 if (@bitCast(u64, val) & 0x1 != 0) {
248 high -= 1;
249 } else {
250 low -= 1;
251 }
252
253 const l64 = u64(low % pow19);
254 const lf = u64((low / pow19) % pow19);
255
256 const h64 = u64(high % pow19);
257 const hf = u64((high / pow19) % pow19);
258
259 if (lf != hf) {
260 l64 = lf;
261 h64 = hf;
262 mid = mid / (pow19 / 10);
263 }
264
265 var mi: i32 = mismatch10(l64, h64);
266 var x: u64 = 1;
267 {
268 var i = i32(lf == hf);
269 while (i < mi) : (i += 1) {
270 x *= 10;
271 }
272 }
273 const m64: u64 = mid / x;
274
275 if (lf != hf)
276 mi += 19;
277
278 var buf_index = u64toa(m64, buffer) - 1;
279
280 if (mi != 0) {
281 buffer[buf_index - 1] += (buffer[buf_index] >= '5');
282 } else {
283 buf_index += 1;
284 }
285
286 return FloatDecimal {
287 .digits = buffer[0..buf_index],
288 .exp = buf_index + mi,
289 };
290}
291
292/// Fixed point conversion algorithm, guaranteed correct, optimal, and best.
293/// @val: The val.
294/// @buf: The output buffer.
295/// &return: The exponent.
296fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
297 assert((val >= 16.0) and (val < 9.007199254740992e15));
298
299 const u = u64(val);
300 const n = f64(u);
301
302 var mid = val - n;
303 var lo = ((fpprev(val) - n) + mid) / 2.0;
304 var hi = ((fpnext(val) - n) + mid) / 2.0;
305
306 var buf_index = u64toa(u, buffer);
307 var exp: i32 = buf_index;
308 var j: i32 = exp;
309 buffer[j] = 0;
310
311 if (mid != 0.0) {
312 while (mid != 0.0) {
313 lo *= 10.0;
314 var ldig = i32(lo);
315 lo -= ldig;
316
317 mid *= 10.0;
318 var mdig = i32(mid);
319 mid -= mdig;
320
321 hi *= 10.0;
322 var hdig = i32(hi);
323 hi -= hdig;
324
325 buffer[j] = mdig + '0';
326 j += 1;
327
328 if(hdig != ldig or j > 50)
329 break;
330 }
331
332 if (mid > 0.5) {
333 buffer[j-1] += 1;
334 } else if ((mid == 0.5) and (buffer[j-1] & 0x1)) {
335 buffer[j-1] += 1;
336 }
337 } else {
338 while (buffer[j-1] == '0') {
339 buffer[j-1] = 0;
340 j -= 1;
341 }
342 }
343
344 buffer[j] = 0;
345
346 return FloatDecimal {
347 .digits = buffer[0..j],
348 .exp = exp,
349 };
350}
351
352fn fpnext(val: f64) -> f64 {
353 return @bitCast(f64, @bitCast(u64, val) + 1);
354}
355
356fn fpprev(val: f64) -> f64 {
357 return @bitCast(f64, @bitCast(u64, val) - 1);
358}
359
360pub const c_digits_lut = []u8 {
361 '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6',
362 '0', '7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3',
363 '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0',
364 '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7',
365 '2', '8', '2', '9', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4',
366 '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', '4', '0', '4', '1',
367 '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8',
368 '4', '9', '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5',
369 '5', '6', '5', '7', '5', '8', '5', '9', '6', '0', '6', '1', '6', '2',
370 '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
371 '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6',
372 '7', '7', '7', '8', '7', '9', '8', '0', '8', '1', '8', '2', '8', '3',
373 '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', '9', '0',
374 '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7',
375 '9', '8', '9', '9',
376};
377
378fn u64toa(value: u64, buffer: []u8) -> usize {
379 const kTen8: u64 = 100000000;
380 const kTen9: u64 = kTen8 * 10;
381 const kTen10: u64 = kTen8 * 100;
382 const kTen11: u64 = kTen8 * 1000;
383 const kTen12: u64 = kTen8 * 10000;
384 const kTen13: u64 = kTen8 * 100000;
385 const kTen14: u64 = kTen8 * 1000000;
386 const kTen15: u64 = kTen8 * 10000000;
387 const kTen16: u64 = kTen8 * kTen8;
388
389 var buf_index: usize = 0;
390
391 if (value < kTen8) {
392 const v = u32(value);
393 if (v < 10000) {
394 const d1: u32 = (v / 100) << 1;
395 const d2: u32 = (v % 100) << 1;
396
397 if (v >= 1000) {
398 buffer[buf_index] = c_digits_lut[d1];
399 buf_index += 1;
400 }
401 if (v >= 100) {
402 buffer[buf_index] = c_digits_lut[d1 + 1];
403 buf_index += 1;
404 }
405 if (v >= 10) {
406 buffer[buf_index] = c_digits_lut[d2];
407 buf_index += 1;
408 }
409 buffer[buf_index] = c_digits_lut[d2 + 1];
410 buf_index += 1;
411 } else {
412 // value = bbbbcccc
413 const b: u32 = v / 10000;
414 const c: u32 = v % 10000;
415
416 const d1: u32 = (b / 100) << 1;
417 const d2: u32 = (b % 100) << 1;
418
419 const d3: u32 = (c / 100) << 1;
420 const d4: u32 = (c % 100) << 1;
421
422 if (value >= 10000000) {
423 buffer[buf_index] = c_digits_lut[d1];
424 buf_index += 1;
425 }
426 if (value >= 1000000) {
427 buffer[buf_index] = c_digits_lut[d1 + 1];
428 buf_index += 1;
429 }
430 if (value >= 100000) {
431 buffer[buf_index] = c_digits_lut[d2];
432 buf_index += 1;
433 }
434 buffer[buf_index] = c_digits_lut[d2 + 1];
435 buf_index += 1;
436
437 buffer[buf_index] = c_digits_lut[d3];
438 buf_index += 1;
439 buffer[buf_index] = c_digits_lut[d3 + 1];
440 buf_index += 1;
441 buffer[buf_index] = c_digits_lut[d4];
442 buf_index += 1;
443 buffer[buf_index] = c_digits_lut[d4 + 1];
444 buf_index += 1;
445 }
446 } else if (value < kTen16) {
447 const v0: u32 = (uint32_t)(value / kTen8);
448 const v1: u32 = (uint32_t)(value % kTen8);
449
450 const b0: u32 = v0 / 10000;
451 const c0: u32 = v0 % 10000;
452
453 const d1: u32 = (b0 / 100) << 1;
454 const d2: u32 = (b0 % 100) << 1;
455
456 const d3: u32 = (c0 / 100) << 1;
457 const d4: u32 = (c0 % 100) << 1;
458
459 const b1: u32 = v1 / 10000;
460 const c1: u32 = v1 % 10000;
461
462 const d5: u32 = (b1 / 100) << 1;
463 const d6: u32 = (b1 % 100) << 1;
464
465 const d7: u32 = (c1 / 100) << 1;
466 const d8: u32 = (c1 % 100) << 1;
467
468 if (value >= kTen15) {
469 buffer[buf_index] = c_digits_lut[d1];
470 buf_index += 1;
471 }
472 if (value >= kTen14) {
473 buffer[buf_index] = c_digits_lut[d1 + 1];
474 buf_index += 1;
475 }
476 if (value >= kTen13) {
477 buffer[buf_index] = c_digits_lut[d2];
478 buf_index += 1;
479 }
480 if (value >= kTen12) {
481 buffer[buf_index] = c_digits_lut[d2 + 1];
482 buf_index += 1;
483 }
484 if (value >= kTen11) {
485 buffer[buf_index] = c_digits_lut[d3];
486 buf_index += 1;
487 }
488 if (value >= kTen10) {
489 buffer[buf_index] = c_digits_lut[d3 + 1];
490 buf_index += 1;
491 }
492 if (value >= kTen9) {
493 buffer[buf_index] = c_digits_lut[d4];
494 buf_index += 1;
495 }
496 if (value >= kTen8) {
497 buffer[buf_index] = c_digits_lut[d4 + 1];
498 buf_index += 1;
499 }
500
501 buffer[buf_index] = c_digits_lut[d5];
502 buf_index += 1;
503 buffer[buf_index] = c_digits_lut[d5 + 1];
504 buf_index += 1;
505 buffer[buf_index] = c_digits_lut[d6];
506 buf_index += 1;
507 buffer[buf_index] = c_digits_lut[d6 + 1];
508 buf_index += 1;
509 buffer[buf_index] = c_digits_lut[d7];
510 buf_index += 1;
511 buffer[buf_index] = c_digits_lut[d7 + 1];
512 buf_index += 1;
513 buffer[buf_index] = c_digits_lut[d8];
514 buf_index += 1;
515 buffer[buf_index] = c_digits_lut[d8];
516 buf_index += 1;
517 buffer[buf_index] = c_digits_lut[d8];
518 buf_index += 1;
519 buffer[buf_index] = c_digits_lut[d8 + 1];
520 buf_index += 1;
521 } else {
522 const a: u32 = (uint32_t)(value / kTen16); // 1 to 1844
523 value %= kTen16;
524
525 if (a < 10) {
526 buffer[buf_index] = (char)('0' + (char)(a));
527 buf_index += 1;
528 } else if (a < 100) {
529 const i: u32 = a << 1;
530 buffer[buf_index] = c_digits_lut[i];
531 buf_index += 1;
532 buffer[buf_index] = c_digits_lut[i + 1];
533 buf_index += 1;
534 } else if (a < 1000) {
535 buffer[buf_index] = (char)('0' + (char)(a / 100));
536 buf_index += 1;
537
538 const i: u32 = (a % 100) << 1;
539 buffer[buf_index] = c_digits_lut[i];
540 buf_index += 1;
541 buffer[buf_index] = c_digits_lut[i + 1];
542 buf_index += 1;
543 } else {
544 const i: u32 = (a / 100) << 1;
545 const j: u32 = (a % 100) << 1;
546 buffer[buf_index] = c_digits_lut[i];
547 buf_index += 1;
548 buffer[buf_index] = c_digits_lut[i + 1];
549 buf_index += 1;
550 buffer[buf_index] = c_digits_lut[j];
551 buf_index += 1;
552 buffer[buf_index] = c_digits_lut[j + 1];
553 buf_index += 1;
554 }
555
556 const v0: u32 = (uint32_t)(value / kTen8);
557 const v1: u32 = (uint32_t)(value % kTen8);
558
559 const b0: u32 = v0 / 10000;
560 const c0: u32 = v0 % 10000;
561
562 const d1: u32 = (b0 / 100) << 1;
563 const d2: u32 = (b0 % 100) << 1;
564
565 const d3: u32 = (c0 / 100) << 1;
566 const d4: u32 = (c0 % 100) << 1;
567
568 const b1: u32 = v1 / 10000;
569 const c1: u32 = v1 % 10000;
570
571 const d5: u32 = (b1 / 100) << 1;
572 const d6: u32 = (b1 % 100) << 1;
573
574 const d7: u32 = (c1 / 100) << 1;
575 const d8: u32 = (c1 % 100) << 1;
576
577 buffer[buf_index] = c_digits_lut[d1];
578 buf_index += 1;
579 buffer[buf_index] = c_digits_lut[d1 + 1];
580 buf_index += 1;
581 buffer[buf_index] = c_digits_lut[d2];
582 buf_index += 1;
583 buffer[buf_index] = c_digits_lut[d2 + 1];
584 buf_index += 1;
585 buffer[buf_index] = c_digits_lut[d3];
586 buf_index += 1;
587 buffer[buf_index] = c_digits_lut[d3 + 1];
588 buf_index += 1;
589 buffer[buf_index] = c_digits_lut[d4];
590 buf_index += 1;
591 buffer[buf_index] = c_digits_lut[d4 + 1];
592 buf_index += 1;
593 buffer[buf_index] = c_digits_lut[d5];
594 buf_index += 1;
595 buffer[buf_index] = c_digits_lut[d5 + 1];
596 buf_index += 1;
597 buffer[buf_index] = c_digits_lut[d6];
598 buf_index += 1;
599 buffer[buf_index] = c_digits_lut[d6 + 1];
600 buf_index += 1;
601 buffer[buf_index] = c_digits_lut[d7];
602 buf_index += 1;
603 buffer[buf_index] = c_digits_lut[d7 + 1];
604 buf_index += 1;
605 buffer[buf_index] = c_digits_lut[d8];
606 buf_index += 1;
607 buffer[buf_index] = c_digits_lut[d8 + 1];
608 buf_index += 1;
609 }
610
611 return buf_index;
612}
613
614fn fpeint(from: f64) -> u128 {
615 const bits = @bitCast(u64, from);
616 assert((bits & ((1 << 52) - 1)) == 0);
617
618 return 1 << ((bits >> 52) - 1023);
619}
620
621
622/// Given two different integers with the same length in terms of the number
623/// of decimal digits, index the digits from the right-most position starting
624/// from zero, find the first index where the digits in the two integers
625/// divergent starting from the highest index.
626/// @a: Integer a.
627/// @b: Integer b.
628/// &returns: An index within [0, 19).
629fn mismatch10(a: u64, b: u64) -> i32 {
630 const pow10 = 10000000000;
631 const af = a / pow10;
632 const bf = b / pow10;
633
634 var i: i32 = 0;
635 var a_copy = a;
636 var b_copy = b;
637
638 if (af != bf) {
639 i = 10;
640 a_copy = af;
641 b_copy = bf;
642 }
643
644 while (true) : (i += 1) {
645 a_copy /= 10;
646 b_copy /= 10;
647
648 if (a_copy == b_copy)
649 return i;
650 }
651}
std/fmt/errol/lookup.zig created+606
......@@ -0,0 +1,606 @@
1pub const HP = struct {
2 val: f64,
3 off: f64,
4};
5pub const lookup_table = []HP{
6 HP{.val=1.000000e+308, .off= -1.097906362944045488e+291 },
7 HP{.val=1.000000e+307, .off= 1.396894023974354241e+290 },
8 HP{.val=1.000000e+306, .off= -1.721606459673645508e+289 },
9 HP{.val=1.000000e+305, .off= 6.074644749446353973e+288 },
10 HP{.val=1.000000e+304, .off= 6.074644749446353567e+287 },
11 HP{.val=1.000000e+303, .off= -1.617650767864564452e+284 },
12 HP{.val=1.000000e+302, .off= -7.629703079084895055e+285 },
13 HP{.val=1.000000e+301, .off= -5.250476025520442286e+284 },
14 HP{.val=1.000000e+300, .off= -5.250476025520441956e+283 },
15 HP{.val=1.000000e+299, .off= -5.250476025520441750e+282 },
16 HP{.val=1.000000e+298, .off= 4.043379652465702264e+281 },
17 HP{.val=1.000000e+297, .off= -1.765280146275637946e+280 },
18 HP{.val=1.000000e+296, .off= 1.865132227937699609e+279 },
19 HP{.val=1.000000e+295, .off= 1.865132227937699609e+278 },
20 HP{.val=1.000000e+294, .off= -6.643646774124810287e+277 },
21 HP{.val=1.000000e+293, .off= 7.537651562646039934e+276 },
22 HP{.val=1.000000e+292, .off= -1.325659897835741608e+275 },
23 HP{.val=1.000000e+291, .off= 4.213909764965371606e+274 },
24 HP{.val=1.000000e+290, .off= -6.172783352786715670e+273 },
25 HP{.val=1.000000e+289, .off= -6.172783352786715670e+272 },
26 HP{.val=1.000000e+288, .off= -7.630473539575035471e+270 },
27 HP{.val=1.000000e+287, .off= -7.525217352494018700e+270 },
28 HP{.val=1.000000e+286, .off= -3.298861103408696612e+269 },
29 HP{.val=1.000000e+285, .off= 1.984084207947955778e+268 },
30 HP{.val=1.000000e+284, .off= -7.921438250845767591e+267 },
31 HP{.val=1.000000e+283, .off= 4.460464822646386735e+266 },
32 HP{.val=1.000000e+282, .off= -3.278224598286209647e+265 },
33 HP{.val=1.000000e+281, .off= -3.278224598286209737e+264 },
34 HP{.val=1.000000e+280, .off= -3.278224598286209961e+263 },
35 HP{.val=1.000000e+279, .off= -5.797329227496039232e+262 },
36 HP{.val=1.000000e+278, .off= 3.649313132040821498e+261 },
37 HP{.val=1.000000e+277, .off= -2.867878510995372374e+259 },
38 HP{.val=1.000000e+276, .off= -5.206914080024985409e+259 },
39 HP{.val=1.000000e+275, .off= 4.018322599210230404e+258 },
40 HP{.val=1.000000e+274, .off= 7.862171215558236495e+257 },
41 HP{.val=1.000000e+273, .off= 5.459765830340732821e+256 },
42 HP{.val=1.000000e+272, .off= -6.552261095746788047e+255 },
43 HP{.val=1.000000e+271, .off= 4.709014147460262298e+254 },
44 HP{.val=1.000000e+270, .off= -4.675381888545612729e+253 },
45 HP{.val=1.000000e+269, .off= -4.675381888545612892e+252 },
46 HP{.val=1.000000e+268, .off= 2.656177514583977380e+251 },
47 HP{.val=1.000000e+267, .off= 2.656177514583977190e+250 },
48 HP{.val=1.000000e+266, .off= -3.071603269111014892e+249 },
49 HP{.val=1.000000e+265, .off= -6.651466258920385440e+248 },
50 HP{.val=1.000000e+264, .off= -4.414051890289528972e+247 },
51 HP{.val=1.000000e+263, .off= -1.617283929500958387e+246 },
52 HP{.val=1.000000e+262, .off= -1.617283929500958241e+245 },
53 HP{.val=1.000000e+261, .off= 7.122615947963323868e+244 },
54 HP{.val=1.000000e+260, .off= -6.533477610574617382e+243 },
55 HP{.val=1.000000e+259, .off= 7.122615947963323982e+242 },
56 HP{.val=1.000000e+258, .off= -5.679971763165996225e+241 },
57 HP{.val=1.000000e+257, .off= -3.012765990014054219e+240 },
58 HP{.val=1.000000e+256, .off= -3.012765990014054219e+239 },
59 HP{.val=1.000000e+255, .off= 1.154743030535854616e+238 },
60 HP{.val=1.000000e+254, .off= 6.364129306223240767e+237 },
61 HP{.val=1.000000e+253, .off= 6.364129306223241129e+236 },
62 HP{.val=1.000000e+252, .off= -9.915202805299840595e+235 },
63 HP{.val=1.000000e+251, .off= -4.827911520448877980e+234 },
64 HP{.val=1.000000e+250, .off= 7.890316691678530146e+233 },
65 HP{.val=1.000000e+249, .off= 7.890316691678529484e+232 },
66 HP{.val=1.000000e+248, .off= -4.529828046727141859e+231 },
67 HP{.val=1.000000e+247, .off= 4.785280507077111924e+230 },
68 HP{.val=1.000000e+246, .off= -6.858605185178205305e+229 },
69 HP{.val=1.000000e+245, .off= -4.432795665958347728e+228 },
70 HP{.val=1.000000e+244, .off= -7.465057564983169531e+227 },
71 HP{.val=1.000000e+243, .off= -7.465057564983169741e+226 },
72 HP{.val=1.000000e+242, .off= -5.096102956370027445e+225 },
73 HP{.val=1.000000e+241, .off= -5.096102956370026952e+224 },
74 HP{.val=1.000000e+240, .off= -1.394611380411992474e+223 },
75 HP{.val=1.000000e+239, .off= 9.188208545617793960e+221 },
76 HP{.val=1.000000e+238, .off= -4.864759732872650359e+221 },
77 HP{.val=1.000000e+237, .off= 5.979453868566904629e+220 },
78 HP{.val=1.000000e+236, .off= -5.316601966265964857e+219 },
79 HP{.val=1.000000e+235, .off= -5.316601966265964701e+218 },
80 HP{.val=1.000000e+234, .off= -1.786584517880693123e+217 },
81 HP{.val=1.000000e+233, .off= 2.625937292600896716e+216 },
82 HP{.val=1.000000e+232, .off= -5.647541102052084079e+215 },
83 HP{.val=1.000000e+231, .off= -5.647541102052083888e+214 },
84 HP{.val=1.000000e+230, .off= -9.956644432600511943e+213 },
85 HP{.val=1.000000e+229, .off= 8.161138937705571862e+211 },
86 HP{.val=1.000000e+228, .off= 7.549087847752475275e+211 },
87 HP{.val=1.000000e+227, .off= -9.283347037202319948e+210 },
88 HP{.val=1.000000e+226, .off= 3.866992716668613820e+209 },
89 HP{.val=1.000000e+225, .off= 7.154577655136347262e+208 },
90 HP{.val=1.000000e+224, .off= 3.045096482051680688e+207 },
91 HP{.val=1.000000e+223, .off= -4.660180717482069567e+206 },
92 HP{.val=1.000000e+222, .off= -4.660180717482070101e+205 },
93 HP{.val=1.000000e+221, .off= -4.660180717482069544e+204 },
94 HP{.val=1.000000e+220, .off= 3.562757926310489022e+202 },
95 HP{.val=1.000000e+219, .off= 3.491561111451748149e+202 },
96 HP{.val=1.000000e+218, .off= -8.265758834125874135e+201 },
97 HP{.val=1.000000e+217, .off= 3.981449442517482365e+200 },
98 HP{.val=1.000000e+216, .off= -2.142154695804195936e+199 },
99 HP{.val=1.000000e+215, .off= 9.339603063548950188e+198 },
100 HP{.val=1.000000e+214, .off= 4.555537330485139746e+197 },
101 HP{.val=1.000000e+213, .off= 1.565496247320257804e+196 },
102 HP{.val=1.000000e+212, .off= 9.040598955232462036e+195 },
103 HP{.val=1.000000e+211, .off= 4.368659762787334780e+194 },
104 HP{.val=1.000000e+210, .off= 7.288621758065539072e+193 },
105 HP{.val=1.000000e+209, .off= -7.311188218325485628e+192 },
106 HP{.val=1.000000e+208, .off= 1.813693016918905189e+191 },
107 HP{.val=1.000000e+207, .off= -3.889357755108838992e+190 },
108 HP{.val=1.000000e+206, .off= -3.889357755108838992e+189 },
109 HP{.val=1.000000e+205, .off= -1.661603547285501360e+188 },
110 HP{.val=1.000000e+204, .off= 1.123089212493670643e+187 },
111 HP{.val=1.000000e+203, .off= 1.123089212493670643e+186 },
112 HP{.val=1.000000e+202, .off= 9.825254086803583029e+185 },
113 HP{.val=1.000000e+201, .off= -3.771878529305654999e+184 },
114 HP{.val=1.000000e+200, .off= 3.026687778748963675e+183 },
115 HP{.val=1.000000e+199, .off= -9.720624048853446693e+182 },
116 HP{.val=1.000000e+198, .off= -1.753554156601940139e+181 },
117 HP{.val=1.000000e+197, .off= 4.885670753607648963e+180 },
118 HP{.val=1.000000e+196, .off= 4.885670753607648963e+179 },
119 HP{.val=1.000000e+195, .off= 2.292223523057028076e+178 },
120 HP{.val=1.000000e+194, .off= 5.534032561245303825e+177 },
121 HP{.val=1.000000e+193, .off= -6.622751331960730683e+176 },
122 HP{.val=1.000000e+192, .off= -4.090088020876139692e+175 },
123 HP{.val=1.000000e+191, .off= -7.255917159731877552e+174 },
124 HP{.val=1.000000e+190, .off= -7.255917159731877992e+173 },
125 HP{.val=1.000000e+189, .off= -2.309309130269787104e+172 },
126 HP{.val=1.000000e+188, .off= -2.309309130269787019e+171 },
127 HP{.val=1.000000e+187, .off= 9.284303438781988230e+170 },
128 HP{.val=1.000000e+186, .off= 2.038295583124628364e+169 },
129 HP{.val=1.000000e+185, .off= 2.038295583124628532e+168 },
130 HP{.val=1.000000e+184, .off= -1.735666841696912925e+167 },
131 HP{.val=1.000000e+183, .off= 5.340512704843477241e+166 },
132 HP{.val=1.000000e+182, .off= -6.453119872723839321e+165 },
133 HP{.val=1.000000e+181, .off= 8.288920849235306587e+164 },
134 HP{.val=1.000000e+180, .off= -9.248546019891598293e+162 },
135 HP{.val=1.000000e+179, .off= 1.954450226518486016e+162 },
136 HP{.val=1.000000e+178, .off= -5.243811844750628197e+161 },
137 HP{.val=1.000000e+177, .off= -7.448980502074320639e+159 },
138 HP{.val=1.000000e+176, .off= -7.448980502074319858e+158 },
139 HP{.val=1.000000e+175, .off= 6.284654753766312753e+158 },
140 HP{.val=1.000000e+174, .off= -6.895756753684458388e+157 },
141 HP{.val=1.000000e+173, .off= -1.403918625579970616e+156 },
142 HP{.val=1.000000e+172, .off= -8.268716285710580522e+155 },
143 HP{.val=1.000000e+171, .off= 4.602779327034313170e+154 },
144 HP{.val=1.000000e+170, .off= -3.441905430931244940e+153 },
145 HP{.val=1.000000e+169, .off= 6.613950516525702884e+152 },
146 HP{.val=1.000000e+168, .off= 6.613950516525702652e+151 },
147 HP{.val=1.000000e+167, .off= -3.860899428741951187e+150 },
148 HP{.val=1.000000e+166, .off= 5.959272394946474605e+149 },
149 HP{.val=1.000000e+165, .off= 1.005101065481665103e+149 },
150 HP{.val=1.000000e+164, .off= -1.783349948587918355e+146 },
151 HP{.val=1.000000e+163, .off= 6.215006036188360099e+146 },
152 HP{.val=1.000000e+162, .off= 6.215006036188360099e+145 },
153 HP{.val=1.000000e+161, .off= -3.774589324822814903e+144 },
154 HP{.val=1.000000e+160, .off= -6.528407745068226929e+142 },
155 HP{.val=1.000000e+159, .off= 7.151530601283157561e+142 },
156 HP{.val=1.000000e+158, .off= 4.712664546348788765e+141 },
157 HP{.val=1.000000e+157, .off= 1.664081977680827856e+140 },
158 HP{.val=1.000000e+156, .off= 1.664081977680827750e+139 },
159 HP{.val=1.000000e+155, .off= -7.176231540910168265e+137 },
160 HP{.val=1.000000e+154, .off= -3.694754568805822650e+137 },
161 HP{.val=1.000000e+153, .off= 2.665969958768462622e+134 },
162 HP{.val=1.000000e+152, .off= -4.625108135904199522e+135 },
163 HP{.val=1.000000e+151, .off= -1.717753238721771919e+134 },
164 HP{.val=1.000000e+150, .off= 1.916440382756262433e+133 },
165 HP{.val=1.000000e+149, .off= -4.897672657515052040e+132 },
166 HP{.val=1.000000e+148, .off= -4.897672657515052198e+131 },
167 HP{.val=1.000000e+147, .off= 2.200361759434233991e+130 },
168 HP{.val=1.000000e+146, .off= 6.636633270027537273e+129 },
169 HP{.val=1.000000e+145, .off= 1.091293881785907977e+128 },
170 HP{.val=1.000000e+144, .off= -2.374543235865110597e+127 },
171 HP{.val=1.000000e+143, .off= -2.374543235865110537e+126 },
172 HP{.val=1.000000e+142, .off= -5.082228484029969099e+125 },
173 HP{.val=1.000000e+141, .off= -1.697621923823895943e+124 },
174 HP{.val=1.000000e+140, .off= -5.928380124081487212e+123 },
175 HP{.val=1.000000e+139, .off= -3.284156248920492522e+122 },
176 HP{.val=1.000000e+138, .off= -3.284156248920492706e+121 },
177 HP{.val=1.000000e+137, .off= -3.284156248920492476e+120 },
178 HP{.val=1.000000e+136, .off= -5.866406127007401066e+119 },
179 HP{.val=1.000000e+135, .off= 3.817030915818506056e+118 },
180 HP{.val=1.000000e+134, .off= 7.851796350329300951e+117 },
181 HP{.val=1.000000e+133, .off= -2.235117235947686077e+116 },
182 HP{.val=1.000000e+132, .off= 9.170432597638723691e+114 },
183 HP{.val=1.000000e+131, .off= 8.797444499042767883e+114 },
184 HP{.val=1.000000e+130, .off= -5.978307824605161274e+113 },
185 HP{.val=1.000000e+129, .off= 1.782556435814758516e+111 },
186 HP{.val=1.000000e+128, .off= -7.517448691651820362e+111 },
187 HP{.val=1.000000e+127, .off= 4.507089332150205498e+110 },
188 HP{.val=1.000000e+126, .off= 7.513223838100711695e+109 },
189 HP{.val=1.000000e+125, .off= 7.513223838100712113e+108 },
190 HP{.val=1.000000e+124, .off= 5.164681255326878494e+107 },
191 HP{.val=1.000000e+123, .off= 2.229003026859587122e+106 },
192 HP{.val=1.000000e+122, .off= -1.440594758724527399e+105 },
193 HP{.val=1.000000e+121, .off= -3.734093374714598783e+104 },
194 HP{.val=1.000000e+120, .off= 1.999653165260579757e+103 },
195 HP{.val=1.000000e+119, .off= 5.583244752745066693e+102 },
196 HP{.val=1.000000e+118, .off= 3.343500010567262234e+101 },
197 HP{.val=1.000000e+117, .off= -5.055542772599503556e+100 },
198 HP{.val=1.000000e+116, .off= -1.555941612946684331e+99 },
199 HP{.val=1.000000e+115, .off= -1.555941612946684331e+98 },
200 HP{.val=1.000000e+114, .off= -1.555941612946684293e+97 },
201 HP{.val=1.000000e+113, .off= -1.555941612946684246e+96 },
202 HP{.val=1.000000e+112, .off= 6.988006530736955847e+95 },
203 HP{.val=1.000000e+111, .off= 4.318022735835818244e+94 },
204 HP{.val=1.000000e+110, .off= -2.356936751417025578e+93 },
205 HP{.val=1.000000e+109, .off= 1.814912928116001926e+92 },
206 HP{.val=1.000000e+108, .off= -3.399899171300282744e+91 },
207 HP{.val=1.000000e+107, .off= 3.118615952970072913e+90 },
208 HP{.val=1.000000e+106, .off= -9.103599905036843605e+89 },
209 HP{.val=1.000000e+105, .off= 6.174169917471802325e+88 },
210 HP{.val=1.000000e+104, .off= -1.915675085734668657e+86 },
211 HP{.val=1.000000e+103, .off= -1.915675085734668864e+85 },
212 HP{.val=1.000000e+102, .off= 2.295048673475466221e+85 },
213 HP{.val=1.000000e+101, .off= 2.295048673475466135e+84 },
214 HP{.val=1.000000e+100, .off= -1.590289110975991792e+83 },
215 HP{.val=1.000000e+99, .off= 3.266383119588331155e+82 },
216 HP{.val=1.000000e+98, .off= 2.309629754856292029e+80 },
217 HP{.val=1.000000e+97, .off= -7.357587384771124533e+80 },
218 HP{.val=1.000000e+96, .off= -4.986165397190889509e+79 },
219 HP{.val=1.000000e+95, .off= -2.021887912715594741e+78 },
220 HP{.val=1.000000e+94, .off= -2.021887912715594638e+77 },
221 HP{.val=1.000000e+93, .off= -4.337729697461918675e+76 },
222 HP{.val=1.000000e+92, .off= -4.337729697461918997e+75 },
223 HP{.val=1.000000e+91, .off= -7.956232486128049702e+74 },
224 HP{.val=1.000000e+90, .off= 3.351588728453609882e+73 },
225 HP{.val=1.000000e+89, .off= 5.246334248081951113e+71 },
226 HP{.val=1.000000e+88, .off= 4.058327554364963672e+71 },
227 HP{.val=1.000000e+87, .off= 4.058327554364963918e+70 },
228 HP{.val=1.000000e+86, .off= -1.463069523067487266e+69 },
229 HP{.val=1.000000e+85, .off= -1.463069523067487314e+68 },
230 HP{.val=1.000000e+84, .off= -5.776660989811589441e+67 },
231 HP{.val=1.000000e+83, .off= -3.080666323096525761e+66 },
232 HP{.val=1.000000e+82, .off= 3.659320343691134468e+65 },
233 HP{.val=1.000000e+81, .off= 7.871812010433421235e+64 },
234 HP{.val=1.000000e+80, .off= -2.660986470836727449e+61 },
235 HP{.val=1.000000e+79, .off= 3.264399249934044627e+62 },
236 HP{.val=1.000000e+78, .off= -8.493621433689703070e+60 },
237 HP{.val=1.000000e+77, .off= 1.721738727445414063e+60 },
238 HP{.val=1.000000e+76, .off= -4.706013449590547218e+59 },
239 HP{.val=1.000000e+75, .off= 7.346021882351880518e+58 },
240 HP{.val=1.000000e+74, .off= 4.835181188197207515e+57 },
241 HP{.val=1.000000e+73, .off= 1.696630320503867482e+56 },
242 HP{.val=1.000000e+72, .off= 5.619818905120542959e+55 },
243 HP{.val=1.000000e+71, .off= -4.188152556421145598e+54 },
244 HP{.val=1.000000e+70, .off= -7.253143638152923145e+53 },
245 HP{.val=1.000000e+69, .off= -7.253143638152923145e+52 },
246 HP{.val=1.000000e+68, .off= 4.719477774861832896e+51 },
247 HP{.val=1.000000e+67, .off= 1.726322421608144052e+50 },
248 HP{.val=1.000000e+66, .off= 5.467766613175255107e+49 },
249 HP{.val=1.000000e+65, .off= 7.909613737163661911e+47 },
250 HP{.val=1.000000e+64, .off= -2.132041900945439564e+47 },
251 HP{.val=1.000000e+63, .off= -5.785795994272697265e+46 },
252 HP{.val=1.000000e+62, .off= -3.502199685943161329e+45 },
253 HP{.val=1.000000e+61, .off= 5.061286470292598274e+44 },
254 HP{.val=1.000000e+60, .off= 5.061286470292598472e+43 },
255 HP{.val=1.000000e+59, .off= 2.831211950439536034e+42 },
256 HP{.val=1.000000e+58, .off= 5.618805100255863927e+41 },
257 HP{.val=1.000000e+57, .off= -4.834669211555366251e+40 },
258 HP{.val=1.000000e+56, .off= -9.190283508143378583e+39 },
259 HP{.val=1.000000e+55, .off= -1.023506702040855158e+38 },
260 HP{.val=1.000000e+54, .off= -7.829154040459624616e+37 },
261 HP{.val=1.000000e+53, .off= 6.779051325638372659e+35 },
262 HP{.val=1.000000e+52, .off= 6.779051325638372290e+34 },
263 HP{.val=1.000000e+51, .off= 6.779051325638371598e+33 },
264 HP{.val=1.000000e+50, .off= -7.629769841091887392e+33 },
265 HP{.val=1.000000e+49, .off= 5.350972305245182400e+32 },
266 HP{.val=1.000000e+48, .off= -4.384584304507619764e+31 },
267 HP{.val=1.000000e+47, .off= -4.384584304507619876e+30 },
268 HP{.val=1.000000e+46, .off= 6.860180964052978705e+28 },
269 HP{.val=1.000000e+45, .off= 7.024271097546444878e+28 },
270 HP{.val=1.000000e+44, .off= -8.821361405306422641e+27 },
271 HP{.val=1.000000e+43, .off= -1.393721169594140991e+26 },
272 HP{.val=1.000000e+42, .off= -4.488571267807591679e+25 },
273 HP{.val=1.000000e+41, .off= -6.200086450407783195e+23 },
274 HP{.val=1.000000e+40, .off= -3.037860284270036669e+23 },
275 HP{.val=1.000000e+39, .off= 6.029083362839682141e+22 },
276 HP{.val=1.000000e+38, .off= 2.251190176543965970e+21 },
277 HP{.val=1.000000e+37, .off= 4.612373417978788577e+20 },
278 HP{.val=1.000000e+36, .off= -4.242063737401796198e+19 },
279 HP{.val=1.000000e+35, .off= 3.136633892082024448e+18 },
280 HP{.val=1.000000e+34, .off= 5.442476901295718400e+17 },
281 HP{.val=1.000000e+33, .off= 5.442476901295718400e+16 },
282 HP{.val=1.000000e+32, .off= -5.366162204393472000e+15 },
283 HP{.val=1.000000e+31, .off= 3.641037050347520000e+14 },
284 HP{.val=1.000000e+30, .off= -1.988462483865600000e+13 },
285 HP{.val=1.000000e+29, .off= 8.566849142784000000e+12 },
286 HP{.val=1.000000e+28, .off= 4.168802631680000000e+11 },
287 HP{.val=1.000000e+27, .off= -1.328755507200000000e+10 },
288 HP{.val=1.000000e+26, .off= -4.764729344000000000e+09 },
289 HP{.val=1.000000e+25, .off= -9.059696640000000000e+08 },
290 HP{.val=1.000000e+24, .off= 1.677721600000000000e+07 },
291 HP{.val=1.000000e+23, .off= 8.388608000000000000e+06 },
292 HP{.val=1.000000e+22, .off= 0.000000000000000000e+00 },
293 HP{.val=1.000000e+21, .off= 0.000000000000000000e+00 },
294 HP{.val=1.000000e+20, .off= 0.000000000000000000e+00 },
295 HP{.val=1.000000e+19, .off= 0.000000000000000000e+00 },
296 HP{.val=1.000000e+18, .off= 0.000000000000000000e+00 },
297 HP{.val=1.000000e+17, .off= 0.000000000000000000e+00 },
298 HP{.val=1.000000e+16, .off= 0.000000000000000000e+00 },
299 HP{.val=1.000000e+15, .off= 0.000000000000000000e+00 },
300 HP{.val=1.000000e+14, .off= 0.000000000000000000e+00 },
301 HP{.val=1.000000e+13, .off= 0.000000000000000000e+00 },
302 HP{.val=1.000000e+12, .off= 0.000000000000000000e+00 },
303 HP{.val=1.000000e+11, .off= 0.000000000000000000e+00 },
304 HP{.val=1.000000e+10, .off= 0.000000000000000000e+00 },
305 HP{.val=1.000000e+09, .off= 0.000000000000000000e+00 },
306 HP{.val=1.000000e+08, .off= 0.000000000000000000e+00 },
307 HP{.val=1.000000e+07, .off= 0.000000000000000000e+00 },
308 HP{.val=1.000000e+06, .off= 0.000000000000000000e+00 },
309 HP{.val=1.000000e+05, .off= 0.000000000000000000e+00 },
310 HP{.val=1.000000e+04, .off= 0.000000000000000000e+00 },
311 HP{.val=1.000000e+03, .off= 0.000000000000000000e+00 },
312 HP{.val=1.000000e+02, .off= 0.000000000000000000e+00 },
313 HP{.val=1.000000e+01, .off= 0.000000000000000000e+00 },
314 HP{.val=1.000000e+00, .off= 0.000000000000000000e+00 },
315 HP{.val=1.000000e-01, .off= -5.551115123125783010e-18 },
316 HP{.val=1.000000e-02, .off= -2.081668171172168436e-19 },
317 HP{.val=1.000000e-03, .off= -2.081668171172168557e-20 },
318 HP{.val=1.000000e-04, .off= -4.792173602385929943e-21 },
319 HP{.val=1.000000e-05, .off= -8.180305391403130547e-22 },
320 HP{.val=1.000000e-06, .off= 4.525188817411374069e-23 },
321 HP{.val=1.000000e-07, .off= 4.525188817411373922e-24 },
322 HP{.val=1.000000e-08, .off= -2.092256083012847109e-25 },
323 HP{.val=1.000000e-09, .off= -6.228159145777985254e-26 },
324 HP{.val=1.000000e-10, .off= -3.643219731549774344e-27 },
325 HP{.val=1.000000e-11, .off= 6.050303071806019080e-28 },
326 HP{.val=1.000000e-12, .off= 2.011335237074438524e-29 },
327 HP{.val=1.000000e-13, .off= -3.037374556340037101e-30 },
328 HP{.val=1.000000e-14, .off= 1.180690645440101289e-32 },
329 HP{.val=1.000000e-15, .off= -7.770539987666107583e-32 },
330 HP{.val=1.000000e-16, .off= 2.090221327596539779e-33 },
331 HP{.val=1.000000e-17, .off= -7.154242405462192144e-34 },
332 HP{.val=1.000000e-18, .off= -7.154242405462192572e-35 },
333 HP{.val=1.000000e-19, .off= 2.475407316473986894e-36 },
334 HP{.val=1.000000e-20, .off= 5.484672854579042914e-37 },
335 HP{.val=1.000000e-21, .off= 9.246254777210362522e-38 },
336 HP{.val=1.000000e-22, .off= -4.859677432657087182e-39 },
337 HP{.val=1.000000e-23, .off= 3.956530198510069291e-40 },
338 HP{.val=1.000000e-24, .off= 7.629950044829717753e-41 },
339 HP{.val=1.000000e-25, .off= -3.849486974919183692e-42 },
340 HP{.val=1.000000e-26, .off= -3.849486974919184170e-43 },
341 HP{.val=1.000000e-27, .off= -3.849486974919184070e-44 },
342 HP{.val=1.000000e-28, .off= 2.876745653839937870e-45 },
343 HP{.val=1.000000e-29, .off= 5.679342582489572168e-46 },
344 HP{.val=1.000000e-30, .off= -8.333642060758598930e-47 },
345 HP{.val=1.000000e-31, .off= -8.333642060758597958e-48 },
346 HP{.val=1.000000e-32, .off= -5.596730997624190224e-49 },
347 HP{.val=1.000000e-33, .off= -5.596730997624190604e-50 },
348 HP{.val=1.000000e-34, .off= 7.232539610818348498e-51 },
349 HP{.val=1.000000e-35, .off= -7.857545194582380514e-53 },
350 HP{.val=1.000000e-36, .off= 5.896157255772251528e-53 },
351 HP{.val=1.000000e-37, .off= -6.632427322784915796e-54 },
352 HP{.val=1.000000e-38, .off= 3.808059826012723592e-55 },
353 HP{.val=1.000000e-39, .off= 7.070712060011985131e-56 },
354 HP{.val=1.000000e-40, .off= 7.070712060011985584e-57 },
355 HP{.val=1.000000e-41, .off= -5.761291134237854167e-59 },
356 HP{.val=1.000000e-42, .off= -3.762312935688689794e-59 },
357 HP{.val=1.000000e-43, .off= -7.745042713519821150e-60 },
358 HP{.val=1.000000e-44, .off= 4.700987842202462817e-61 },
359 HP{.val=1.000000e-45, .off= 1.589480203271891964e-62 },
360 HP{.val=1.000000e-46, .off= -2.299904345391321765e-63 },
361 HP{.val=1.000000e-47, .off= 2.561826340437695261e-64 },
362 HP{.val=1.000000e-48, .off= 2.561826340437695345e-65 },
363 HP{.val=1.000000e-49, .off= 6.360053438741614633e-66 },
364 HP{.val=1.000000e-50, .off= -7.616223705782342295e-68 },
365 HP{.val=1.000000e-51, .off= -7.616223705782343324e-69 },
366 HP{.val=1.000000e-52, .off= -7.616223705782342295e-70 },
367 HP{.val=1.000000e-53, .off= -3.079876214757872338e-70 },
368 HP{.val=1.000000e-54, .off= -3.079876214757872821e-71 },
369 HP{.val=1.000000e-55, .off= 5.423954167728123147e-73 },
370 HP{.val=1.000000e-56, .off= -3.985444122640543680e-73 },
371 HP{.val=1.000000e-57, .off= 4.504255013759498850e-74 },
372 HP{.val=1.000000e-58, .off= -2.570494266573869991e-75 },
373 HP{.val=1.000000e-59, .off= -2.570494266573869930e-76 },
374 HP{.val=1.000000e-60, .off= 2.956653608686574324e-77 },
375 HP{.val=1.000000e-61, .off= -3.952281235388981376e-78 },
376 HP{.val=1.000000e-62, .off= -3.952281235388981376e-79 },
377 HP{.val=1.000000e-63, .off= -6.651083908855995172e-80 },
378 HP{.val=1.000000e-64, .off= 3.469426116645307030e-81 },
379 HP{.val=1.000000e-65, .off= 7.686305293937516319e-82 },
380 HP{.val=1.000000e-66, .off= 2.415206322322254927e-83 },
381 HP{.val=1.000000e-67, .off= 5.709643179581793251e-84 },
382 HP{.val=1.000000e-68, .off= -6.644495035141475923e-85 },
383 HP{.val=1.000000e-69, .off= 3.650620143794581913e-86 },
384 HP{.val=1.000000e-70, .off= 4.333966503770636492e-88 },
385 HP{.val=1.000000e-71, .off= 8.476455383920859113e-88 },
386 HP{.val=1.000000e-72, .off= 3.449543675455986564e-89 },
387 HP{.val=1.000000e-73, .off= 3.077238576654418974e-91 },
388 HP{.val=1.000000e-74, .off= 4.234998629903623140e-91 },
389 HP{.val=1.000000e-75, .off= 4.234998629903623412e-92 },
390 HP{.val=1.000000e-76, .off= 7.303182045714702338e-93 },
391 HP{.val=1.000000e-77, .off= 7.303182045714701699e-94 },
392 HP{.val=1.000000e-78, .off= 1.121271649074855759e-96 },
393 HP{.val=1.000000e-79, .off= 1.121271649074855863e-97 },
394 HP{.val=1.000000e-80, .off= 3.857468248661243988e-97 },
395 HP{.val=1.000000e-81, .off= 3.857468248661244248e-98 },
396 HP{.val=1.000000e-82, .off= 3.857468248661244410e-99 },
397 HP{.val=1.000000e-83, .off= -3.457651055545315679e-100 },
398 HP{.val=1.000000e-84, .off= -3.457651055545315933e-101 },
399 HP{.val=1.000000e-85, .off= 2.257285900866059216e-102 },
400 HP{.val=1.000000e-86, .off= -8.458220892405268345e-103 },
401 HP{.val=1.000000e-87, .off= -1.761029146610688867e-104 },
402 HP{.val=1.000000e-88, .off= 6.610460535632536565e-105 },
403 HP{.val=1.000000e-89, .off= -3.853901567171494935e-106 },
404 HP{.val=1.000000e-90, .off= 5.062493089968513723e-108 },
405 HP{.val=1.000000e-91, .off= -2.218844988608365240e-108 },
406 HP{.val=1.000000e-92, .off= 1.187522883398155383e-109 },
407 HP{.val=1.000000e-93, .off= 9.703442563414457296e-110 },
408 HP{.val=1.000000e-94, .off= 4.380992763404268896e-111 },
409 HP{.val=1.000000e-95, .off= 1.054461638397900823e-112 },
410 HP{.val=1.000000e-96, .off= 9.370789450913819736e-113 },
411 HP{.val=1.000000e-97, .off= -3.623472756142303998e-114 },
412 HP{.val=1.000000e-98, .off= 6.122223899149788839e-115 },
413 HP{.val=1.000000e-99, .off= -1.999189980260288281e-116 },
414 HP{.val=1.000000e-100, .off= -1.999189980260288281e-117 },
415 HP{.val=1.000000e-101, .off= -5.171617276904849634e-118 },
416 HP{.val=1.000000e-102, .off= 6.724985085512256320e-119 },
417 HP{.val=1.000000e-103, .off= 4.246526260008692213e-120 },
418 HP{.val=1.000000e-104, .off= 7.344599791888147003e-121 },
419 HP{.val=1.000000e-105, .off= 3.472007877038828407e-122 },
420 HP{.val=1.000000e-106, .off= 5.892377823819652194e-123 },
421 HP{.val=1.000000e-107, .off= -1.585470431324073925e-125 },
422 HP{.val=1.000000e-108, .off= -3.940375084977444795e-125 },
423 HP{.val=1.000000e-109, .off= 7.869099673288519908e-127 },
424 HP{.val=1.000000e-110, .off= -5.122196348054018581e-127 },
425 HP{.val=1.000000e-111, .off= -8.815387795168313713e-128 },
426 HP{.val=1.000000e-112, .off= 5.034080131510290214e-129 },
427 HP{.val=1.000000e-113, .off= 2.148774313452247863e-130 },
428 HP{.val=1.000000e-114, .off= -5.064490231692858416e-131 },
429 HP{.val=1.000000e-115, .off= -5.064490231692858166e-132 },
430 HP{.val=1.000000e-116, .off= 5.708726942017560559e-134 },
431 HP{.val=1.000000e-117, .off= -2.951229134482377772e-134 },
432 HP{.val=1.000000e-118, .off= 1.451398151372789513e-135 },
433 HP{.val=1.000000e-119, .off= -1.300243902286690040e-136 },
434 HP{.val=1.000000e-120, .off= 2.139308664787659449e-137 },
435 HP{.val=1.000000e-121, .off= 2.139308664787659329e-138 },
436 HP{.val=1.000000e-122, .off= -5.922142664292847471e-139 },
437 HP{.val=1.000000e-123, .off= -5.922142664292846912e-140 },
438 HP{.val=1.000000e-124, .off= 6.673875037395443799e-141 },
439 HP{.val=1.000000e-125, .off= -1.198636026159737932e-142 },
440 HP{.val=1.000000e-126, .off= 5.361789860136246995e-143 },
441 HP{.val=1.000000e-127, .off= -2.838742497733733936e-144 },
442 HP{.val=1.000000e-128, .off= -5.401408859568103261e-145 },
443 HP{.val=1.000000e-129, .off= 7.411922949603743011e-146 },
444 HP{.val=1.000000e-130, .off= -8.604741811861064385e-147 },
445 HP{.val=1.000000e-131, .off= 1.405673664054439890e-148 },
446 HP{.val=1.000000e-132, .off= 1.405673664054439933e-149 },
447 HP{.val=1.000000e-133, .off= -6.414963426504548053e-150 },
448 HP{.val=1.000000e-134, .off= -3.971014335704864578e-151 },
449 HP{.val=1.000000e-135, .off= -3.971014335704864748e-152 },
450 HP{.val=1.000000e-136, .off= -1.523438813303585576e-154 },
451 HP{.val=1.000000e-137, .off= 2.234325152653707766e-154 },
452 HP{.val=1.000000e-138, .off= -6.715683724786540160e-155 },
453 HP{.val=1.000000e-139, .off= -2.986513359186437306e-156 },
454 HP{.val=1.000000e-140, .off= 1.674949597813692102e-157 },
455 HP{.val=1.000000e-141, .off= -4.151879098436469092e-158 },
456 HP{.val=1.000000e-142, .off= -4.151879098436469295e-159 },
457 HP{.val=1.000000e-143, .off= 4.952540739454407825e-160 },
458 HP{.val=1.000000e-144, .off= 4.952540739454407667e-161 },
459 HP{.val=1.000000e-145, .off= 8.508954738630531443e-162 },
460 HP{.val=1.000000e-146, .off= -2.604839008794855481e-163 },
461 HP{.val=1.000000e-147, .off= 2.952057864917838382e-164 },
462 HP{.val=1.000000e-148, .off= 6.425118410988271757e-165 },
463 HP{.val=1.000000e-149, .off= 2.083792728400229858e-166 },
464 HP{.val=1.000000e-150, .off= -6.295358232172964237e-168 },
465 HP{.val=1.000000e-151, .off= 6.153785555826519421e-168 },
466 HP{.val=1.000000e-152, .off= -6.564942029880634994e-169 },
467 HP{.val=1.000000e-153, .off= -3.915207116191644540e-170 },
468 HP{.val=1.000000e-154, .off= 2.709130168030831503e-171 },
469 HP{.val=1.000000e-155, .off= -1.431080634608215966e-172 },
470 HP{.val=1.000000e-156, .off= -4.018712386257620994e-173 },
471 HP{.val=1.000000e-157, .off= 5.684906682427646782e-174 },
472 HP{.val=1.000000e-158, .off= -6.444617153428937489e-175 },
473 HP{.val=1.000000e-159, .off= 1.136335243981427681e-176 },
474 HP{.val=1.000000e-160, .off= 1.136335243981427725e-177 },
475 HP{.val=1.000000e-161, .off= -2.812077463003137395e-178 },
476 HP{.val=1.000000e-162, .off= 4.591196362592922204e-179 },
477 HP{.val=1.000000e-163, .off= 7.675893789924613703e-180 },
478 HP{.val=1.000000e-164, .off= 3.820022005759999543e-181 },
479 HP{.val=1.000000e-165, .off= -9.998177244457686588e-183 },
480 HP{.val=1.000000e-166, .off= -4.012217555824373639e-183 },
481 HP{.val=1.000000e-167, .off= -2.467177666011174334e-185 },
482 HP{.val=1.000000e-168, .off= -4.953592503130188139e-185 },
483 HP{.val=1.000000e-169, .off= -2.011795792799518887e-186 },
484 HP{.val=1.000000e-170, .off= 1.665450095113817423e-187 },
485 HP{.val=1.000000e-171, .off= 1.665450095113817487e-188 },
486 HP{.val=1.000000e-172, .off= -4.080246604750770577e-189 },
487 HP{.val=1.000000e-173, .off= -4.080246604750770677e-190 },
488 HP{.val=1.000000e-174, .off= 4.085789420184387951e-192 },
489 HP{.val=1.000000e-175, .off= 4.085789420184388146e-193 },
490 HP{.val=1.000000e-176, .off= 4.085789420184388146e-194 },
491 HP{.val=1.000000e-177, .off= 4.792197640035244894e-194 },
492 HP{.val=1.000000e-178, .off= 4.792197640035244742e-195 },
493 HP{.val=1.000000e-179, .off= -2.057206575616014662e-196 },
494 HP{.val=1.000000e-180, .off= -2.057206575616014662e-197 },
495 HP{.val=1.000000e-181, .off= -4.732755097354788053e-198 },
496 HP{.val=1.000000e-182, .off= -4.732755097354787867e-199 },
497 HP{.val=1.000000e-183, .off= -5.522105321379546765e-201 },
498 HP{.val=1.000000e-184, .off= -5.777891238658996019e-201 },
499 HP{.val=1.000000e-185, .off= 7.542096444923057046e-203 },
500 HP{.val=1.000000e-186, .off= 8.919335748431433483e-203 },
501 HP{.val=1.000000e-187, .off= -1.287071881492476028e-204 },
502 HP{.val=1.000000e-188, .off= 5.091932887209967018e-205 },
503 HP{.val=1.000000e-189, .off= -6.868701054107114024e-206 },
504 HP{.val=1.000000e-190, .off= -1.885103578558330118e-207 },
505 HP{.val=1.000000e-191, .off= -1.885103578558330205e-208 },
506 HP{.val=1.000000e-192, .off= -9.671974634103305058e-209 },
507 HP{.val=1.000000e-193, .off= -4.805180224387695640e-210 },
508 HP{.val=1.000000e-194, .off= -1.763433718315439838e-211 },
509 HP{.val=1.000000e-195, .off= -9.367799983496079132e-212 },
510 HP{.val=1.000000e-196, .off= -4.615071067758179837e-213 },
511 HP{.val=1.000000e-197, .off= 1.325840076914194777e-214 },
512 HP{.val=1.000000e-198, .off= 8.751979007754662425e-215 },
513 HP{.val=1.000000e-199, .off= 1.789973760091724198e-216 },
514 HP{.val=1.000000e-200, .off= 1.789973760091724077e-217 },
515 HP{.val=1.000000e-201, .off= 5.416018159916171171e-218 },
516 HP{.val=1.000000e-202, .off= -3.649092839644947067e-219 },
517 HP{.val=1.000000e-203, .off= -3.649092839644947067e-220 },
518 HP{.val=1.000000e-204, .off= -1.080338554413850956e-222 },
519 HP{.val=1.000000e-205, .off= -1.080338554413850841e-223 },
520 HP{.val=1.000000e-206, .off= -2.874486186850417807e-223 },
521 HP{.val=1.000000e-207, .off= 7.499710055933455072e-224 },
522 HP{.val=1.000000e-208, .off= -9.790617015372999087e-225 },
523 HP{.val=1.000000e-209, .off= -4.387389805589732612e-226 },
524 HP{.val=1.000000e-210, .off= -4.387389805589732612e-227 },
525 HP{.val=1.000000e-211, .off= -8.608661063232909897e-228 },
526 HP{.val=1.000000e-212, .off= 4.582811616902018972e-229 },
527 HP{.val=1.000000e-213, .off= 4.582811616902019155e-230 },
528 HP{.val=1.000000e-214, .off= 8.705146829444184930e-231 },
529 HP{.val=1.000000e-215, .off= -4.177150709750081830e-232 },
530 HP{.val=1.000000e-216, .off= -4.177150709750082366e-233 },
531 HP{.val=1.000000e-217, .off= -8.202868690748290237e-234 },
532 HP{.val=1.000000e-218, .off= -3.170721214500530119e-235 },
533 HP{.val=1.000000e-219, .off= -3.170721214500529857e-236 },
534 HP{.val=1.000000e-220, .off= 7.606440013180328441e-238 },
535 HP{.val=1.000000e-221, .off= -1.696459258568569049e-238 },
536 HP{.val=1.000000e-222, .off= -4.767838333426821244e-239 },
537 HP{.val=1.000000e-223, .off= 2.910609353718809138e-240 },
538 HP{.val=1.000000e-224, .off= -1.888420450747209784e-241 },
539 HP{.val=1.000000e-225, .off= 4.110366804835314035e-242 },
540 HP{.val=1.000000e-226, .off= 7.859608839574391006e-243 },
541 HP{.val=1.000000e-227, .off= 5.516332567862468419e-244 },
542 HP{.val=1.000000e-228, .off= -3.270953451057244613e-245 },
543 HP{.val=1.000000e-229, .off= -6.932322625607124670e-246 },
544 HP{.val=1.000000e-230, .off= -4.643966891513449762e-247 },
545 HP{.val=1.000000e-231, .off= 1.076922443720738305e-248 },
546 HP{.val=1.000000e-232, .off= -2.498633390800628939e-249 },
547 HP{.val=1.000000e-233, .off= 4.205533798926934891e-250 },
548 HP{.val=1.000000e-234, .off= 4.205533798926934891e-251 },
549 HP{.val=1.000000e-235, .off= 4.205533798926934697e-252 },
550 HP{.val=1.000000e-236, .off= -4.523850562697497656e-253 },
551 HP{.val=1.000000e-237, .off= 9.320146633177728298e-255 },
552 HP{.val=1.000000e-238, .off= 9.320146633177728062e-256 },
553 HP{.val=1.000000e-239, .off= -7.592774752331086440e-256 },
554 HP{.val=1.000000e-240, .off= 3.063212017229987840e-257 },
555 HP{.val=1.000000e-241, .off= 3.063212017229987562e-258 },
556 HP{.val=1.000000e-242, .off= 3.063212017229987562e-259 },
557 HP{.val=1.000000e-243, .off= 4.616527473176159842e-261 },
558 HP{.val=1.000000e-244, .off= 6.965550922098544975e-261 },
559 HP{.val=1.000000e-245, .off= 6.965550922098544749e-262 },
560 HP{.val=1.000000e-246, .off= 4.424965697574744679e-263 },
561 HP{.val=1.000000e-247, .off= -1.926497363734756420e-264 },
562 HP{.val=1.000000e-248, .off= 2.043167049583681740e-265 },
563 HP{.val=1.000000e-249, .off= -5.399953725388390154e-266 },
564 HP{.val=1.000000e-250, .off= -5.399953725388389982e-267 },
565 HP{.val=1.000000e-251, .off= -1.523328321757102663e-268 },
566 HP{.val=1.000000e-252, .off= 5.745344310051561161e-269 },
567 HP{.val=1.000000e-253, .off= -6.369110076296211879e-270 },
568 HP{.val=1.000000e-254, .off= 8.773957906638504842e-271 },
569 HP{.val=1.000000e-255, .off= -6.904595826956931908e-273 },
570 HP{.val=1.000000e-256, .off= 2.267170882721243669e-273 },
571 HP{.val=1.000000e-257, .off= 2.267170882721243669e-274 },
572 HP{.val=1.000000e-258, .off= 4.577819683828225398e-275 },
573 HP{.val=1.000000e-259, .off= -6.975424321706684210e-276 },
574 HP{.val=1.000000e-260, .off= 3.855741933482293648e-277 },
575 HP{.val=1.000000e-261, .off= 1.599248963651256552e-278 },
576 HP{.val=1.000000e-262, .off= -1.221367248637539543e-279 },
577 HP{.val=1.000000e-263, .off= -1.221367248637539494e-280 },
578 HP{.val=1.000000e-264, .off= -1.221367248637539647e-281 },
579 HP{.val=1.000000e-265, .off= 1.533140771175737943e-282 },
580 HP{.val=1.000000e-266, .off= 1.533140771175737895e-283 },
581 HP{.val=1.000000e-267, .off= 1.533140771175738074e-284 },
582 HP{.val=1.000000e-268, .off= 4.223090009274641634e-285 },
583 HP{.val=1.000000e-269, .off= 4.223090009274641634e-286 },
584 HP{.val=1.000000e-270, .off= -4.183001359784432924e-287 },
585 HP{.val=1.000000e-271, .off= 3.697709298708449474e-288 },
586 HP{.val=1.000000e-272, .off= 6.981338739747150474e-289 },
587 HP{.val=1.000000e-273, .off= -9.436808465446354751e-290 },
588 HP{.val=1.000000e-274, .off= 3.389869038611071740e-291 },
589 HP{.val=1.000000e-275, .off= 6.596538414625427829e-292 },
590 HP{.val=1.000000e-276, .off= -9.436808465446354618e-293 },
591 HP{.val=1.000000e-277, .off= 3.089243784609725523e-294 },
592 HP{.val=1.000000e-278, .off= 6.220756847123745836e-295 },
593 HP{.val=1.000000e-279, .off= -5.522417137303829470e-296 },
594 HP{.val=1.000000e-280, .off= 4.263561183052483059e-297 },
595 HP{.val=1.000000e-281, .off= -1.852675267170212272e-298 },
596 HP{.val=1.000000e-282, .off= -1.852675267170212378e-299 },
597 HP{.val=1.000000e-283, .off= 5.314789322934508480e-300 },
598 HP{.val=1.000000e-284, .off= -3.644541414696392675e-301 },
599 HP{.val=1.000000e-285, .off= -7.377595888709267777e-302 },
600 HP{.val=1.000000e-286, .off= -5.044436842451220838e-303 },
601 HP{.val=1.000000e-287, .off= -2.127988034628661760e-304 },
602 HP{.val=1.000000e-288, .off= -5.773549044406860911e-305 },
603 HP{.val=1.000000e-289, .off= -1.216597782184112068e-306 },
604 HP{.val=1.000000e-290, .off= -6.912786859962547924e-307 },
605 HP{.val=1.000000e-291, .off= 3.767567660872018813e-308 },
606};
std/fmt/index.zig created+470
......@@ -0,0 +1,470 @@
1const math = @import("../math/index.zig");
2const debug = @import("../debug.zig");
3const assert = debug.assert;
4const mem = @import("../mem.zig");
5const builtin = @import("builtin");
6const errol3 = @import("errol/index.zig").errol3;
7
8const max_int_digits = 65;
9
10const State = enum { // TODO put inside format function and make sure the name and debug info is correct
11 Start,
12 OpenBrace,
13 CloseBrace,
14 Integer,
15 IntegerWidth,
16 Character,
17 Buf,
18 BufWidth,
19};
20
21/// Renders fmt string with args, calling output with slices of bytes.
22/// Return false from output function and output will not be called again.
23/// Returns false if output ever returned false, true otherwise.
24pub fn format(context: var, output: fn(@typeOf(context), []const u8)->bool,
25 comptime fmt: []const u8, args: ...) -> bool
26{
27 comptime var start_index = 0;
28 comptime var state = State.Start;
29 comptime var next_arg = 0;
30 comptime var radix = 0;
31 comptime var uppercase = false;
32 comptime var width = 0;
33 comptime var width_start = 0;
34
35 inline for (fmt) |c, i| {
36 switch (state) {
37 State.Start => switch (c) {
38 '{' => {
39 // TODO if you make this an if statement with `and` then it breaks
40 if (start_index < i) {
41 if (!output(context, fmt[start_index..i]))
42 return false;
43 }
44 state = State.OpenBrace;
45 },
46 '}' => {
47 if (start_index < i) {
48 if (!output(context, fmt[start_index..i]))
49 return false;
50 }
51 state = State.CloseBrace;
52 },
53 else => {},
54 },
55 State.OpenBrace => switch (c) {
56 '{' => {
57 state = State.Start;
58 start_index = i;
59 },
60 '}' => {
61 if (!formatValue(args[next_arg], context, output))
62 return false;
63 next_arg += 1;
64 state = State.Start;
65 start_index = i + 1;
66 },
67 'd' => {
68 radix = 10;
69 uppercase = false;
70 width = 0;
71 state = State.Integer;
72 },
73 'x' => {
74 radix = 16;
75 uppercase = false;
76 width = 0;
77 state = State.Integer;
78 },
79 'X' => {
80 radix = 16;
81 uppercase = true;
82 width = 0;
83 state = State.Integer;
84 },
85 'c' => {
86 state = State.Character;
87 },
88 's' => {
89 state = State.Buf;
90 },
91 else => @compileError("Unknown format character: " ++ []u8{c}),
92 },
93 State.Buf => switch (c) {
94 '}' => {
95 return output(context, args[next_arg]);
96 },
97 '0' ... '9' => {
98 width_start = i;
99 state = State.BufWidth;
100 },
101 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
102 },
103 State.CloseBrace => switch (c) {
104 '}' => {
105 state = State.Start;
106 start_index = i;
107 },
108 else => @compileError("Single '}' encountered in format string"),
109 },
110 State.Integer => switch (c) {
111 '}' => {
112 if (!formatInt(args[next_arg], radix, uppercase, width, context, output))
113 return false;
114 next_arg += 1;
115 state = State.Start;
116 start_index = i + 1;
117 },
118 '0' ... '9' => {
119 width_start = i;
120 state = State.IntegerWidth;
121 },
122 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
123 },
124 State.IntegerWidth => switch (c) {
125 '}' => {
126 width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
127 if (!formatInt(args[next_arg], radix, uppercase, width, context, output))
128 return false;
129 next_arg += 1;
130 state = State.Start;
131 start_index = i + 1;
132 },
133 '0' ... '9' => {},
134 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
135 },
136 State.BufWidth => switch (c) {
137 '}' => {
138 width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
139 if (!formatBuf(args[next_arg], width, context, output))
140 return false;
141 next_arg += 1;
142 state = State.Start;
143 start_index = i + 1;
144 },
145 '0' ... '9' => {},
146 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
147 },
148 State.Character => switch (c) {
149 '}' => {
150 if (!formatAsciiChar(args[next_arg], context, output))
151 return false;
152 next_arg += 1;
153 state = State.Start;
154 start_index = i + 1;
155 },
156 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
157 },
158 }
159 }
160 comptime {
161 if (args.len != next_arg) {
162 @compileError("Unused arguments");
163 }
164 if (state != State.Start) {
165 @compileError("Incomplete format string: " ++ fmt);
166 }
167 }
168 if (start_index < fmt.len) {
169 if (!output(context, fmt[start_index..]))
170 return false;
171 }
172
173 return true;
174}
175
176pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
177 const T = @typeOf(value);
178 switch (@typeId(T)) {
179 builtin.TypeId.Int => {
180 return formatInt(value, 10, false, 0, context, output);
181 },
182 builtin.TypeId.Float => {
183 return formatFloat(value, context, output);
184 },
185 builtin.TypeId.Void => {
186 return output(context, "void");
187 },
188 builtin.TypeId.Bool => {
189 return output(context, if (value) "true" else "false");
190 },
191 builtin.TypeId.Nullable => {
192 if (value) |payload| {
193 return formatValue(payload, context, output);
194 } else {
195 return output(context, "null");
196 }
197 },
198 builtin.TypeId.ErrorUnion => {
199 if (value) |payload| {
200 return formatValue(payload, context, output);
201 } else |err| {
202 return formatValue(err, context, output);
203 }
204 },
205 builtin.TypeId.Error => {
206 if (!output(context, "error."))
207 return false;
208 return output(context, @errorName(value));
209 },
210 else => if (@canImplicitCast([]const u8, value)) {
211 const casted_value = ([]const u8)(value);
212 return output(context, casted_value);
213 } else {
214 @compileError("Unable to format type '" ++ @typeName(T) ++ "'");
215 },
216 }
217}
218
219pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
220 return output(context, (&c)[0..1]);
221}
222
223pub fn formatBuf(buf: []const u8, width: usize,
224 context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool
225{
226 if (!output(context, buf))
227 return false;
228
229 var leftover_padding = if (width > buf.len) (width - buf.len) else return true;
230 const pad_byte: u8 = ' ';
231 while (leftover_padding > 0) : (leftover_padding -= 1) {
232 if (!output(context, (&pad_byte)[0..1]))
233 return false;
234 }
235
236 return true;
237}
238
239pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
240 var buffer: [20]u8 = undefined;
241 const float_decimal = errol3(f64(value), buffer[0..]);
242 if (!output(context, float_decimal.digits[0..1]))
243 return false;
244 if (!output(context, "."))
245 return false;
246 if (!output(context, float_decimal.digits[1..]))
247 return false;
248 if (!output(context, "e"))
249 return false;
250 if (!formatInt(float_decimal.exp, 10, false, 0, context, output))
251 return false;
252 return true;
253}
254
255pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
256 context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool
257{
258 if (@typeOf(value).is_signed) {
259 return formatIntSigned(value, base, uppercase, width, context, output);
260 } else {
261 return formatIntUnsigned(value, base, uppercase, width, context, output);
262 }
263}
264
265fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
266 context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool
267{
268 const uint = @IntType(false, @typeOf(value).bit_count);
269 if (value < 0) {
270 const minus_sign: u8 = '-';
271 if (!output(context, (&minus_sign)[0..1]))
272 return false;
273 const new_value = uint(-(value + 1)) + 1;
274 const new_width = if (width == 0) 0 else (width - 1);
275 return formatIntUnsigned(new_value, base, uppercase, new_width, context, output);
276 } else if (width == 0) {
277 return formatIntUnsigned(uint(value), base, uppercase, width, context, output);
278 } else {
279 const plus_sign: u8 = '+';
280 if (!output(context, (&plus_sign)[0..1]))
281 return false;
282 const new_value = uint(value);
283 const new_width = if (width == 0) 0 else (width - 1);
284 return formatIntUnsigned(new_value, base, uppercase, new_width, context, output);
285 }
286}
287
288fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
289 context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool
290{
291 // max_int_digits accounts for the minus sign. when printing an unsigned
292 // number we don't need to do that.
293 var buf: [max_int_digits - 1]u8 = undefined;
294 var a = value;
295 var index: usize = buf.len;
296
297 while (true) {
298 const digit = a % base;
299 index -= 1;
300 buf[index] = digitToChar(u8(digit), uppercase);
301 a /= base;
302 if (a == 0)
303 break;
304 }
305
306 const digits_buf = buf[index..];
307 const padding = if (width > digits_buf.len) (width - digits_buf.len) else 0;
308
309 if (padding > index) {
310 const zero_byte: u8 = '0';
311 var leftover_padding = padding - index;
312 while (true) {
313 if (!output(context, (&zero_byte)[0..1]))
314 return false;
315 leftover_padding -= 1;
316 if (leftover_padding == 0)
317 break;
318 }
319 mem.set(u8, buf[0..index], '0');
320 return output(context, buf);
321 } else {
322 const padded_buf = buf[index - padding..];
323 mem.set(u8, padded_buf[0..padding], '0');
324 return output(context, padded_buf);
325 }
326}
327
328pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width: usize) -> usize {
329 var context = FormatIntBuf {
330 .out_buf = out_buf,
331 .index = 0,
332 };
333 _ = formatInt(value, base, uppercase, width, &context, formatIntCallback);
334 return context.index;
335}
336const FormatIntBuf = struct {
337 out_buf: []u8,
338 index: usize,
339};
340fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) -> bool {
341 mem.copy(u8, context.out_buf[context.index..], bytes);
342 context.index += bytes.len;
343 return true;
344}
345
346pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {
347 var x: T = 0;
348
349 for (buf) |c| {
350 const digit = %return charToDigit(c, radix);
351 x = %return math.mul(T, x, radix);
352 x = %return math.add(T, x, digit);
353 }
354
355 return x;
356}
357
358error InvalidChar;
359fn charToDigit(c: u8, radix: u8) -> %u8 {
360 const value = switch (c) {
361 '0' ... '9' => c - '0',
362 'A' ... 'Z' => c - 'A' + 10,
363 'a' ... 'z' => c - 'a' + 10,
364 else => return error.InvalidChar,
365 };
366
367 if (value >= radix)
368 return error.InvalidChar;
369
370 return value;
371}
372
373fn digitToChar(digit: u8, uppercase: bool) -> u8 {
374 return switch (digit) {
375 0 ... 9 => digit + '0',
376 10 ... 35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),
377 else => unreachable,
378 };
379}
380
381const BufPrintContext = struct {
382 remaining: []u8,
383};
384
385fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> bool {
386 mem.copy(u8, context.remaining, bytes);
387 context.remaining = context.remaining[bytes.len..];
388 return true;
389}
390
391pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> []u8 {
392 var context = BufPrintContext { .remaining = buf, };
393 _ = format(&context, bufPrintWrite, fmt, args);
394 return buf[0..buf.len - context.remaining.len];
395}
396
397pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) -> %[]u8 {
398 var size: usize = 0;
399 _ = format(&size, countSize, fmt, args);
400 const buf = %return allocator.alloc(u8, size);
401 return bufPrint(buf, fmt, args);
402}
403
404fn countSize(size: &usize, bytes: []const u8) -> bool {
405 *size += bytes.len;
406 return true;
407}
408
409test "buf print int" {
410 var buffer: [max_int_digits]u8 = undefined;
411 const buf = buffer[0..];
412 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 2, false, 0), "-101111000110000101001110"));
413 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 10, false, 0), "-12345678"));
414 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, false, 0), "-bc614e"));
415 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, true, 0), "-BC614E"));
416
417 assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(12345678), 10, true, 0), "12345678"));
418
419 assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(666), 10, false, 6), "000666"));
420 assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, 6), "001234"));
421 assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, 1), "1234"));
422
423 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(42), 10, false, 3), "+42"));
424 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, 3), "-42"));
425}
426
427fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: usize) -> []u8 {
428 return buf[0..formatIntBuf(buf, value, base, uppercase, width)];
429}
430
431test "parse u64 digit too big" {
432 _ = parseUnsigned(u64, "123a", 10) %% |err| {
433 if (err == error.InvalidChar) return;
434 unreachable;
435 };
436 unreachable;
437}
438
439test "parse unsigned comptime" {
440 comptime {
441 assert(%%parseUnsigned(usize, "2", 10) == 2);
442 }
443}
444
445test "fmt.format" {
446 {
447 var buf1: [32]u8 = undefined;
448 const value: ?i32 = 1234;
449 const result = bufPrint(buf1[0..], "nullable: {}\n", value);
450 assert(mem.eql(u8, result, "nullable: 1234\n"));
451 }
452 {
453 var buf1: [32]u8 = undefined;
454 const value: ?i32 = null;
455 const result = bufPrint(buf1[0..], "nullable: {}\n", value);
456 assert(mem.eql(u8, result, "nullable: null\n"));
457 }
458 {
459 var buf1: [32]u8 = undefined;
460 const value: %i32 = 1234;
461 const result = bufPrint(buf1[0..], "error union: {}\n", value);
462 assert(mem.eql(u8, result, "error union: 1234\n"));
463 }
464 {
465 var buf1: [32]u8 = undefined;
466 const value: %i32 = error.InvalidChar;
467 const result = bufPrint(buf1[0..], "error union: {}\n", value);
468 assert(mem.eql(u8, result, "error union: error.InvalidChar\n"));
469 }
470}
std/hash_map.zig+1-1
......@@ -1,6 +1,6 @@
11const debug = @import("debug.zig");
22const assert = debug.assert;
3const math = @import("math.zig");
3const math = @import("math/index.zig");
44const mem = @import("mem.zig");
55const Allocator = mem.Allocator;
66const builtin = @import("builtin");
std/index.zig+4-4
......@@ -14,9 +14,9 @@ pub const dwarf = @import("dwarf.zig");
1414pub const elf = @import("elf.zig");
1515pub const empty_import = @import("empty.zig");
1616pub const endian = @import("endian.zig");
17pub const fmt = @import("fmt.zig");
17pub const fmt = @import("fmt/index.zig");
1818pub const io = @import("io.zig");
19pub const math = @import("math.zig");
19pub const math = @import("math/index.zig");
2020pub const mem = @import("mem.zig");
2121pub const net = @import("net.zig");
2222pub const os = @import("os/index.zig");
......@@ -41,9 +41,9 @@ test "std" {
4141 _ = @import("elf.zig");
4242 _ = @import("empty.zig");
4343 _ = @import("endian.zig");
44 _ = @import("fmt.zig");
44 _ = @import("fmt/index.zig");
4545 _ = @import("io.zig");
46 _ = @import("math.zig");
46 _ = @import("math/index.zig");
4747 _ = @import("mem.zig");
4848 _ = @import("net.zig");
4949 _ = @import("os/index.zig");
std/io.zig+2-2
......@@ -8,13 +8,13 @@ const system = switch(builtin.os) {
88};
99
1010const errno = @import("os/errno.zig");
11const math = @import("math.zig");
11const math = @import("math/index.zig");
1212const debug = @import("debug.zig");
1313const assert = debug.assert;
1414const os = @import("os/index.zig");
1515const mem = @import("mem.zig");
1616const Buffer = @import("buffer.zig").Buffer;
17const fmt = @import("fmt.zig");
17const fmt = @import("fmt/index.zig");
1818
1919const is_posix = builtin.os != builtin.Os.windows;
2020const is_windows = builtin.os == builtin.Os.windows;
std/math.zig deleted-395
......@@ -1,395 +0,0 @@
1const assert = @import("debug.zig").assert;
2const builtin = @import("builtin");
3
4pub const Cmp = enum {
5 Less,
6 Equal,
7 Greater,
8};
9
10pub fn min(x: var, y: var) -> @typeOf(x + y) {
11 if (x < y) x else y
12}
13
14test "math.min" {
15 assert(min(i32(-1), i32(2)) == -1);
16}
17
18pub fn max(x: var, y: var) -> @typeOf(x + y) {
19 if (x > y) x else y
20}
21
22test "math.max" {
23 assert(max(i32(-1), i32(2)) == 2);
24}
25
26error Overflow;
27pub fn mul(comptime T: type, a: T, b: T) -> %T {
28 var answer: T = undefined;
29 if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer
30}
31
32error Overflow;
33pub fn add(comptime T: type, a: T, b: T) -> %T {
34 var answer: T = undefined;
35 if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer
36}
37
38error Overflow;
39pub fn sub(comptime T: type, a: T, b: T) -> %T {
40 var answer: T = undefined;
41 if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer
42}
43
44pub fn negate(x: var) -> %@typeOf(x) {
45 return sub(@typeOf(x), 0, x);
46}
47
48error Overflow;
49pub fn shl(comptime T: type, a: T, b: T) -> %T {
50 var answer: T = undefined;
51 if (@shlWithOverflow(T, a, b, &answer)) error.Overflow else answer
52}
53
54test "math overflow functions" {
55 testOverflow();
56 comptime testOverflow();
57}
58
59fn testOverflow() {
60 assert(%%mul(i32, 3, 4) == 12);
61 assert(%%add(i32, 3, 4) == 7);
62 assert(%%sub(i32, 3, 4) == -1);
63 assert(%%shl(i32, 0b11, 4) == 0b110000);
64}
65
66
67pub fn log(comptime base: usize, value: var) -> @typeOf(value) {
68 const T = @typeOf(value);
69 switch (@typeId(T)) {
70 builtin.TypeId.Int => {
71 if (base == 2) {
72 return T.bit_count - 1 - @clz(value);
73 } else {
74 @compileError("TODO implement log for non base 2 integers");
75 }
76 },
77 builtin.TypeId.Float => {
78 @compileError("TODO implement log for floats");
79 },
80 else => {
81 @compileError("log expects integer or float, found '" ++ @typeName(T) ++ "'");
82 },
83 }
84}
85
86error Overflow;
87pub fn absInt(x: var) -> %@typeOf(x) {
88 const T = @typeOf(x);
89 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
90 comptime assert(T.is_signed); // must pass a signed integer to absInt
91 if (x == @minValue(@typeOf(x)))
92 return error.Overflow;
93 {
94 @setDebugSafety(this, false);
95 return if (x < 0) -x else x;
96 }
97}
98
99test "math.absInt" {
100 testAbsInt();
101 comptime testAbsInt();
102}
103fn testAbsInt() {
104 assert(%%absInt(i32(-10)) == 10);
105 assert(%%absInt(i32(10)) == 10);
106}
107
108pub fn absFloat(x: var) -> @typeOf(x) {
109 comptime assert(@typeId(@typeOf(x)) == builtin.TypeId.Float);
110 return if (x < 0) -x else x;
111}
112
113test "math.absFloat" {
114 testAbsFloat();
115 comptime testAbsFloat();
116}
117fn testAbsFloat() {
118 assert(absFloat(f32(-10.0)) == 10.0);
119 assert(absFloat(f32(10.0)) == 10.0);
120}
121
122error DivisionByZero;
123error Overflow;
124pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T {
125 @setDebugSafety(this, false);
126 if (denominator == 0)
127 return error.DivisionByZero;
128 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
129 return error.Overflow;
130 return @divTrunc(numerator, denominator);
131}
132
133test "math.divTrunc" {
134 testDivTrunc();
135 comptime testDivTrunc();
136}
137fn testDivTrunc() {
138 assert(%%divTrunc(i32, 5, 3) == 1);
139 assert(%%divTrunc(i32, -5, 3) == -1);
140 if (divTrunc(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
141 if (divTrunc(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
142
143 assert(%%divTrunc(f32, 5.0, 3.0) == 1.0);
144 assert(%%divTrunc(f32, -5.0, 3.0) == -1.0);
145}
146
147error DivisionByZero;
148error Overflow;
149pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T {
150 @setDebugSafety(this, false);
151 if (denominator == 0)
152 return error.DivisionByZero;
153 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
154 return error.Overflow;
155 return @divFloor(numerator, denominator);
156}
157
158test "math.divFloor" {
159 testDivFloor();
160 comptime testDivFloor();
161}
162fn testDivFloor() {
163 assert(%%divFloor(i32, 5, 3) == 1);
164 assert(%%divFloor(i32, -5, 3) == -2);
165 if (divFloor(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
166 if (divFloor(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
167
168 assert(%%divFloor(f32, 5.0, 3.0) == 1.0);
169 assert(%%divFloor(f32, -5.0, 3.0) == -2.0);
170}
171
172error DivisionByZero;
173error Overflow;
174error UnexpectedRemainder;
175pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T {
176 @setDebugSafety(this, false);
177 if (denominator == 0)
178 return error.DivisionByZero;
179 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
180 return error.Overflow;
181 const result = @divTrunc(numerator, denominator);
182 if (result * denominator != numerator)
183 return error.UnexpectedRemainder;
184 return result;
185}
186
187test "math.divExact" {
188 testDivExact();
189 comptime testDivExact();
190}
191fn testDivExact() {
192 assert(%%divExact(i32, 10, 5) == 2);
193 assert(%%divExact(i32, -10, 5) == -2);
194 if (divExact(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
195 if (divExact(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
196 if (divExact(i32, 5, 2)) |_| unreachable else |err| assert(err == error.UnexpectedRemainder);
197
198 assert(%%divExact(f32, 10.0, 5.0) == 2.0);
199 assert(%%divExact(f32, -10.0, 5.0) == -2.0);
200 if (divExact(f32, 5.0, 2.0)) |_| unreachable else |err| assert(err == error.UnexpectedRemainder);
201}
202
203error DivisionByZero;
204error NegativeDenominator;
205pub fn mod(comptime T: type, numerator: T, denominator: T) -> %T {
206 @setDebugSafety(this, false);
207 if (denominator == 0)
208 return error.DivisionByZero;
209 if (denominator < 0)
210 return error.NegativeDenominator;
211 return @mod(numerator, denominator);
212}
213
214test "math.mod" {
215 testMod();
216 comptime testMod();
217}
218fn testMod() {
219 assert(%%mod(i32, -5, 3) == 1);
220 assert(%%mod(i32, 5, 3) == 2);
221 if (mod(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
222 if (mod(i32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
223
224 assert(%%mod(f32, -5, 3) == 1);
225 assert(%%mod(f32, 5, 3) == 2);
226 if (mod(f32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
227 if (mod(f32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
228}
229
230error DivisionByZero;
231error NegativeDenominator;
232pub fn rem(comptime T: type, numerator: T, denominator: T) -> %T {
233 @setDebugSafety(this, false);
234 if (denominator == 0)
235 return error.DivisionByZero;
236 if (denominator < 0)
237 return error.NegativeDenominator;
238 return @rem(numerator, denominator);
239}
240
241test "math.rem" {
242 testRem();
243 comptime testRem();
244}
245fn testRem() {
246 assert(%%rem(i32, -5, 3) == -2);
247 assert(%%rem(i32, 5, 3) == 2);
248 if (rem(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
249 if (rem(i32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
250
251 assert(%%rem(f32, -5, 3) == -2);
252 assert(%%rem(f32, 5, 3) == 2);
253 if (rem(f32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
254 if (rem(f32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
255}
256
257fn isNan(comptime T: type, x: T) -> bool {
258 assert(@typeId(T) == builtin.TypeId.Float);
259 if (T == f32) {
260 const bits = bitCast(u32, x);
261 return (bits & 0x7fffffff) > 0x7f800000;
262 } else if (T == f64) {
263 const bits = bitCast(u64, x);
264 return (bits & (@maxValue(u64) >> 1)) > (u64(0x7ff) << 52);
265 } else if (T == c_longdouble) {
266 @compileError("TODO support isNan for c_longdouble");
267 } else {
268 unreachable;
269 }
270}
271
272// TODO this should be a builtin
273fn bitCast(comptime DestType: type, value: var) -> DestType {
274 assert(@sizeOf(DestType) == @sizeOf(@typeOf(value)));
275 return *@ptrCast(&const DestType, &value);
276}
277
278pub fn floor(x: var) -> @typeOf(x) {
279 switch (@typeOf(x)) {
280 f32 => floor_f32(x),
281 f64 => floor_f64(x),
282 c_longdouble => @compileError("TODO support floor for c_longdouble"),
283 else => @compileError("Invalid type for floor: " ++ @typeName(@typeOf(x))),
284 }
285}
286
287fn floor_f32(x: f32) -> f32 {
288 var i = bitCast(u32, x);
289 const e = i32((i >> 23) & 0xff) -% 0x7f;
290 if (e >= 23)
291 return x;
292 if (e >= 0) {
293 const m = bitCast(u32, 0x007fffff >> e);
294 if ((i & m) == 0)
295 return x;
296 if (i >> 31 != 0)
297 i +%= m;
298 i &= ~m;
299 } else {
300 if (i >> 31 == 0)
301 return 0;
302 if (i <<% 1 != 0)
303 return -1.0;
304 }
305 return bitCast(f32, i);
306}
307
308fn floor_f64(x: f64) -> f64 {
309 const DBL_EPSILON = 2.22044604925031308085e-16;
310 const toint = 1.0 / DBL_EPSILON;
311
312 var i = bitCast(u64, x);
313 const e = (i >> 52) & 0x7ff;
314
315 if (e >= 0x3ff +% 52 or x == 0)
316 return x;
317 // y = int(x) - x, where int(x) is an integer neighbor of x
318 const y = {
319 @setFloatMode(this, builtin.FloatMode.Strict);
320 if (i >> 63 != 0) {
321 x - toint + toint - x
322 } else {
323 x + toint - toint - x
324 }
325 };
326 // special case because of non-nearest rounding modes
327 if (e <= 0x3ff - 1) {
328 if (i >> 63 != 0)
329 return -1.0;
330 return 0.0;
331 }
332 if (y > 0)
333 return x + y - 1;
334 return x + y;
335}
336
337test "math.floor" {
338 assert(floor(f32(1.234)) == 1.0);
339 assert(floor(f32(-1.234)) == -2.0);
340 assert(floor(f32(999.0)) == 999.0);
341 assert(floor(f32(-999.0)) == -999.0);
342
343 assert(floor(f64(1.234)) == 1.0);
344 assert(floor(f64(-1.234)) == -2.0);
345 assert(floor(f64(999.0)) == 999.0);
346 assert(floor(f64(-999.0)) == -999.0);
347}
348
349/// Returns the absolute value of the integer parameter.
350/// Result is an unsigned integer.
351pub fn absCast(x: var) -> @IntType(false, @typeOf(x).bit_count) {
352 const uint = @IntType(false, @typeOf(x).bit_count);
353 if (x >= 0)
354 return uint(x);
355
356 return uint(-(x + 1)) + 1;
357}
358
359test "math.absCast" {
360 assert(absCast(i32(-999)) == 999);
361 assert(@typeOf(absCast(i32(-999))) == u32);
362
363 assert(absCast(i32(999)) == 999);
364 assert(@typeOf(absCast(i32(999))) == u32);
365
366 assert(absCast(i32(@minValue(i32))) == -@minValue(i32));
367 assert(@typeOf(absCast(i32(@minValue(i32)))) == u32);
368}
369
370/// Returns the negation of the integer parameter.
371/// Result is a signed integer.
372error Overflow;
373pub fn negateCast(x: var) -> %@IntType(true, @typeOf(x).bit_count) {
374 if (@typeOf(x).is_signed)
375 return negate(x);
376
377 const int = @IntType(true, @typeOf(x).bit_count);
378 if (x > -@minValue(int))
379 return error.Overflow;
380
381 if (x == -@minValue(int))
382 return @minValue(int);
383
384 return -int(x);
385}
386
387test "math.negateCast" {
388 assert(%%negateCast(u32(999)) == -999);
389 assert(@typeOf(%%negateCast(u32(999))) == i32);
390
391 assert(%%negateCast(u32(-@minValue(i32))) == @minValue(i32));
392 assert(@typeOf(%%negateCast(u32(-@minValue(i32)))) == i32);
393
394 if (negateCast(u32(@maxValue(i32) + 10))) |_| unreachable else |err| assert(err == error.Overflow);
395}
std/math/fabs.zig created+49
......@@ -0,0 +1,49 @@
1const assert = @import("../debug.zig").assert;
2
3pub fn fabs(x: var) -> @typeOf(x) {
4 const T = @typeOf(x);
5 switch (T) {
6 f32 => fabs32(x),
7 f64 => fabs64(x),
8 else => @compileError("fabs not implemented for " ++ @typeName(T)),
9 }
10}
11
12fn fabs32(x: f32) -> f32 {
13 var u = @bitCast(u32, x);
14 u &= 0x7FFFFFFF;
15 @bitCast(f32, u)
16}
17
18fn fabs64(x: f64) -> f64 {
19 var u = @bitCast(u64, x);
20 u &= @maxValue(u64) >> 1;
21 @bitCast(f64, u)
22}
23
24test "fabs" {
25 assert(fabs(f32(1.0)) == fabs32(1.0));
26 assert(fabs(f64(1.0)) == fabs64(1.0));
27 comptime {
28 assert(fabs(f32(1.0)) == fabs32(1.0));
29 assert(fabs(f64(1.0)) == fabs64(1.0));
30 }
31}
32
33test "fabs32" {
34 assert(fabs64(1.0) == 1.0);
35 assert(fabs64(-1.0) == 1.0);
36 comptime {
37 assert(fabs64(1.0) == 1.0);
38 assert(fabs64(-1.0) == 1.0);
39 }
40}
41
42test "fabs64" {
43 assert(fabs64(1.0) == 1.0);
44 assert(fabs64(-1.0) == 1.0);
45 comptime {
46 assert(fabs64(1.0) == 1.0);
47 assert(fabs64(-1.0) == 1.0);
48 }
49}
std/math/frexp.zig created+89
......@@ -0,0 +1,89 @@
1const assert = @import("../debug.zig").assert;
2const math = @import("index.zig");
3
4pub fn frexp(x: var, e: &i32) -> @typeOf(x) {
5 const T = @typeOf(x);
6 switch (T) {
7 f32 => frexp32(x, e),
8 f64 => frexp64(x, e),
9 else => @compileError("frexp not implemented for " ++ @typeName(T)),
10 }
11}
12
13fn frexp32(x_: f32, e: &i32) -> f32 {
14 var x = x_;
15 var y = @bitCast(u32, x);
16 const ee = i32(y >> 23) & 0xFF;
17
18 if (ee == 0) {
19 if (x != 0) {
20 x = frexp32(x * 0x1.0p64, e);
21 *e -= 64;
22 } else {
23 *e = 0;
24 }
25 return x;
26 } else if (ee == 0xFF) {
27 return x;
28 }
29
30 *e = ee - 0x7E;
31 y &= 0x807FFFFF;
32 y |= 0x3F000000;
33 @bitCast(f32, y)
34}
35
36fn frexp64(x_: f64, e: &i32) -> f64 {
37 var x = x_;
38 var y = @bitCast(u64, x);
39 const ee = i32(y >> 52) & 0x7FF;
40
41 if (ee == 0) {
42 if (x != 0) {
43 x = frexp64(x * 0x1.0p64, e);
44 *e -= 64;
45 } else {
46 *e = 0;
47 }
48 return x;
49 } else if (ee == 0x7FF) {
50 return x;
51 }
52
53 *e = ee - 0x3FE;
54 y &= 0x800FFFFFFFFFFFFF;
55 y |= 0x3FE0000000000000;
56 @bitCast(f64, y)
57}
58
59test "frexp" {
60 var i0: i32 = undefined;
61 var i1: i32 = undefined;
62
63 assert(frexp(f32(1.3), &i0) == frexp32(1.3, &i1));
64 assert(frexp(f64(1.3), &i0) == frexp64(1.3, &i1));
65}
66
67test "frexp32" {
68 const epsilon = 0.000001;
69 var i: i32 = undefined;
70 var d: f32 = undefined;
71
72 d = frexp32(1.3, &i);
73 assert(math.approxEq(f32, d, 0.65, epsilon) and i == 1);
74
75 d = frexp32(78.0234, &i);
76 assert(math.approxEq(f32, d, 0.609558, epsilon) and i == 7);
77}
78
79test "frexp64" {
80 const epsilon = 0.000001;
81 var i: i32 = undefined;
82 var d: f64 = undefined;
83
84 d = frexp64(1.3, &i);
85 assert(math.approxEq(f64, d, 0.65, epsilon) and i == 1);
86
87 d = frexp64(78.0234, &i);
88 assert(math.approxEq(f64, d, 0.609558, epsilon) and i == 7);
89}
std/math/index.zig created+389
......@@ -0,0 +1,389 @@
1const assert = @import("../debug.zig").assert;
2const builtin = @import("builtin");
3
4pub const frexp = @import("frexp.zig").frexp;
5
6pub const Cmp = enum {
7 Less,
8 Equal,
9 Greater,
10};
11
12pub fn min(x: var, y: var) -> @typeOf(x + y) {
13 if (x < y) x else y
14}
15
16test "math.min" {
17 assert(min(i32(-1), i32(2)) == -1);
18}
19
20pub fn max(x: var, y: var) -> @typeOf(x + y) {
21 if (x > y) x else y
22}
23
24test "math.max" {
25 assert(max(i32(-1), i32(2)) == 2);
26}
27
28error Overflow;
29pub fn mul(comptime T: type, a: T, b: T) -> %T {
30 var answer: T = undefined;
31 if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer
32}
33
34error Overflow;
35pub fn add(comptime T: type, a: T, b: T) -> %T {
36 var answer: T = undefined;
37 if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer
38}
39
40error Overflow;
41pub fn sub(comptime T: type, a: T, b: T) -> %T {
42 var answer: T = undefined;
43 if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer
44}
45
46pub fn negate(x: var) -> %@typeOf(x) {
47 return sub(@typeOf(x), 0, x);
48}
49
50error Overflow;
51pub fn shl(comptime T: type, a: T, b: T) -> %T {
52 var answer: T = undefined;
53 if (@shlWithOverflow(T, a, b, &answer)) error.Overflow else answer
54}
55
56test "math overflow functions" {
57 testOverflow();
58 comptime testOverflow();
59}
60
61fn testOverflow() {
62 assert(%%mul(i32, 3, 4) == 12);
63 assert(%%add(i32, 3, 4) == 7);
64 assert(%%sub(i32, 3, 4) == -1);
65 assert(%%shl(i32, 0b11, 4) == 0b110000);
66}
67
68
69pub fn log(comptime base: usize, value: var) -> @typeOf(value) {
70 const T = @typeOf(value);
71 switch (@typeId(T)) {
72 builtin.TypeId.Int => {
73 if (base == 2) {
74 return T.bit_count - 1 - @clz(value);
75 } else {
76 @compileError("TODO implement log for non base 2 integers");
77 }
78 },
79 builtin.TypeId.Float => {
80 @compileError("TODO implement log for floats");
81 },
82 else => {
83 @compileError("log expects integer or float, found '" ++ @typeName(T) ++ "'");
84 },
85 }
86}
87
88error Overflow;
89pub fn absInt(x: var) -> %@typeOf(x) {
90 const T = @typeOf(x);
91 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
92 comptime assert(T.is_signed); // must pass a signed integer to absInt
93 if (x == @minValue(@typeOf(x)))
94 return error.Overflow;
95 {
96 @setDebugSafety(this, false);
97 return if (x < 0) -x else x;
98 }
99}
100
101test "math.absInt" {
102 testAbsInt();
103 comptime testAbsInt();
104}
105fn testAbsInt() {
106 assert(%%absInt(i32(-10)) == 10);
107 assert(%%absInt(i32(10)) == 10);
108}
109
110pub const absFloat = @import("fabs.zig").fabs;
111
112error DivisionByZero;
113error Overflow;
114pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T {
115 @setDebugSafety(this, false);
116 if (denominator == 0)
117 return error.DivisionByZero;
118 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
119 return error.Overflow;
120 return @divTrunc(numerator, denominator);
121}
122
123test "math.divTrunc" {
124 testDivTrunc();
125 comptime testDivTrunc();
126}
127fn testDivTrunc() {
128 assert(%%divTrunc(i32, 5, 3) == 1);
129 assert(%%divTrunc(i32, -5, 3) == -1);
130 if (divTrunc(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
131 if (divTrunc(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
132
133 assert(%%divTrunc(f32, 5.0, 3.0) == 1.0);
134 assert(%%divTrunc(f32, -5.0, 3.0) == -1.0);
135}
136
137error DivisionByZero;
138error Overflow;
139pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T {
140 @setDebugSafety(this, false);
141 if (denominator == 0)
142 return error.DivisionByZero;
143 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
144 return error.Overflow;
145 return @divFloor(numerator, denominator);
146}
147
148test "math.divFloor" {
149 testDivFloor();
150 comptime testDivFloor();
151}
152fn testDivFloor() {
153 assert(%%divFloor(i32, 5, 3) == 1);
154 assert(%%divFloor(i32, -5, 3) == -2);
155 if (divFloor(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
156 if (divFloor(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
157
158 assert(%%divFloor(f32, 5.0, 3.0) == 1.0);
159 assert(%%divFloor(f32, -5.0, 3.0) == -2.0);
160}
161
162error DivisionByZero;
163error Overflow;
164error UnexpectedRemainder;
165pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T {
166 @setDebugSafety(this, false);
167 if (denominator == 0)
168 return error.DivisionByZero;
169 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
170 return error.Overflow;
171 const result = @divTrunc(numerator, denominator);
172 if (result * denominator != numerator)
173 return error.UnexpectedRemainder;
174 return result;
175}
176
177test "math.divExact" {
178 testDivExact();
179 comptime testDivExact();
180}
181fn testDivExact() {
182 assert(%%divExact(i32, 10, 5) == 2);
183 assert(%%divExact(i32, -10, 5) == -2);
184 if (divExact(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
185 if (divExact(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
186 if (divExact(i32, 5, 2)) |_| unreachable else |err| assert(err == error.UnexpectedRemainder);
187
188 assert(%%divExact(f32, 10.0, 5.0) == 2.0);
189 assert(%%divExact(f32, -10.0, 5.0) == -2.0);
190 if (divExact(f32, 5.0, 2.0)) |_| unreachable else |err| assert(err == error.UnexpectedRemainder);
191}
192
193error DivisionByZero;
194error NegativeDenominator;
195pub fn mod(comptime T: type, numerator: T, denominator: T) -> %T {
196 @setDebugSafety(this, false);
197 if (denominator == 0)
198 return error.DivisionByZero;
199 if (denominator < 0)
200 return error.NegativeDenominator;
201 return @mod(numerator, denominator);
202}
203
204test "math.mod" {
205 testMod();
206 comptime testMod();
207}
208fn testMod() {
209 assert(%%mod(i32, -5, 3) == 1);
210 assert(%%mod(i32, 5, 3) == 2);
211 if (mod(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
212 if (mod(i32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
213
214 assert(%%mod(f32, -5, 3) == 1);
215 assert(%%mod(f32, 5, 3) == 2);
216 if (mod(f32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
217 if (mod(f32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
218}
219
220error DivisionByZero;
221error NegativeDenominator;
222pub fn rem(comptime T: type, numerator: T, denominator: T) -> %T {
223 @setDebugSafety(this, false);
224 if (denominator == 0)
225 return error.DivisionByZero;
226 if (denominator < 0)
227 return error.NegativeDenominator;
228 return @rem(numerator, denominator);
229}
230
231test "math.rem" {
232 testRem();
233 comptime testRem();
234}
235fn testRem() {
236 assert(%%rem(i32, -5, 3) == -2);
237 assert(%%rem(i32, 5, 3) == 2);
238 if (rem(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
239 if (rem(i32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
240
241 assert(%%rem(f32, -5, 3) == -2);
242 assert(%%rem(f32, 5, 3) == 2);
243 if (rem(f32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
244 if (rem(f32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
245}
246
247fn isNan(comptime T: type, x: T) -> bool {
248 assert(@typeId(T) == builtin.TypeId.Float);
249 if (T == f32) {
250 const bits = @bitCast(u32, x);
251 return (bits & 0x7fffffff) > 0x7f800000;
252 } else if (T == f64) {
253 const bits = @bitCast(u64, x);
254 return (bits & (@maxValue(u64) >> 1)) > (u64(0x7ff) << 52);
255 } else if (T == c_longdouble) {
256 @compileError("TODO support isNan for c_longdouble");
257 } else {
258 unreachable;
259 }
260}
261
262pub fn floor(x: var) -> @typeOf(x) {
263 switch (@typeOf(x)) {
264 f32 => floor_f32(x),
265 f64 => floor_f64(x),
266 c_longdouble => @compileError("TODO support floor for c_longdouble"),
267 else => @compileError("Invalid type for floor: " ++ @typeName(@typeOf(x))),
268 }
269}
270
271fn floor_f32(x: f32) -> f32 {
272 var i = @bitCast(u32, x);
273 const e = i32((i >> 23) & 0xff) -% 0x7f;
274 if (e >= 23)
275 return x;
276 if (e >= 0) {
277 const m = @bitCast(u32, 0x007fffff >> e);
278 if ((i & m) == 0)
279 return x;
280 if (i >> 31 != 0)
281 i +%= m;
282 i &= ~m;
283 } else {
284 if (i >> 31 == 0)
285 return 0;
286 if (i <<% 1 != 0)
287 return -1.0;
288 }
289 return @bitCast(f32, i);
290}
291
292fn floor_f64(x: f64) -> f64 {
293 const DBL_EPSILON = 2.22044604925031308085e-16;
294 const toint = 1.0 / DBL_EPSILON;
295
296 var i = @bitCast(u64, x);
297 const e = (i >> 52) & 0x7ff;
298
299 if (e >= 0x3ff +% 52 or x == 0)
300 return x;
301 // y = int(x) - x, where int(x) is an integer neighbor of x
302 const y = {
303 @setFloatMode(this, builtin.FloatMode.Strict);
304 if (i >> 63 != 0) {
305 x - toint + toint - x
306 } else {
307 x + toint - toint - x
308 }
309 };
310 // special case because of non-nearest rounding modes
311 if (e <= 0x3ff - 1) {
312 if (i >> 63 != 0)
313 return -1.0;
314 return 0.0;
315 }
316 if (y > 0)
317 return x + y - 1;
318 return x + y;
319}
320
321test "math.floor" {
322 assert(floor(f32(1.234)) == 1.0);
323 assert(floor(f32(-1.234)) == -2.0);
324 assert(floor(f32(999.0)) == 999.0);
325 assert(floor(f32(-999.0)) == -999.0);
326
327 assert(floor(f64(1.234)) == 1.0);
328 assert(floor(f64(-1.234)) == -2.0);
329 assert(floor(f64(999.0)) == 999.0);
330 assert(floor(f64(-999.0)) == -999.0);
331}
332
333/// Returns the absolute value of the integer parameter.
334/// Result is an unsigned integer.
335pub fn absCast(x: var) -> @IntType(false, @typeOf(x).bit_count) {
336 const uint = @IntType(false, @typeOf(x).bit_count);
337 if (x >= 0)
338 return uint(x);
339
340 return uint(-(x + 1)) + 1;
341}
342
343test "math.absCast" {
344 assert(absCast(i32(-999)) == 999);
345 assert(@typeOf(absCast(i32(-999))) == u32);
346
347 assert(absCast(i32(999)) == 999);
348 assert(@typeOf(absCast(i32(999))) == u32);
349
350 assert(absCast(i32(@minValue(i32))) == -@minValue(i32));
351 assert(@typeOf(absCast(i32(@minValue(i32)))) == u32);
352}
353
354/// Returns the negation of the integer parameter.
355/// Result is a signed integer.
356error Overflow;
357pub fn negateCast(x: var) -> %@IntType(true, @typeOf(x).bit_count) {
358 if (@typeOf(x).is_signed)
359 return negate(x);
360
361 const int = @IntType(true, @typeOf(x).bit_count);
362 if (x > -@minValue(int))
363 return error.Overflow;
364
365 if (x == -@minValue(int))
366 return @minValue(int);
367
368 return -int(x);
369}
370
371test "math.negateCast" {
372 assert(%%negateCast(u32(999)) == -999);
373 assert(@typeOf(%%negateCast(u32(999))) == i32);
374
375 assert(%%negateCast(u32(-@minValue(i32))) == @minValue(i32));
376 assert(@typeOf(%%negateCast(u32(-@minValue(i32)))) == i32);
377
378 if (negateCast(u32(@maxValue(i32) + 10))) |_| unreachable else |err| assert(err == error.Overflow);
379}
380
381test "math" {
382 _ = @import("frexp.zig");
383}
384
385
386pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) -> bool {
387 comptime assert(@typeId(T) == builtin.TypeId.Float);
388 absFloat(x - y) < epsilon
389}
std/mem.zig+1-1
......@@ -1,6 +1,6 @@
11const debug = @import("debug.zig");
22const assert = debug.assert;
3const math = @import("math.zig");
3const math = @import("math/index.zig");
44const os = @import("os/index.zig");
55const io = @import("io.zig");
66const builtin = @import("builtin");
std/os/path.zig+1-1
......@@ -3,7 +3,7 @@ const Os = builtin.Os;
33const debug = @import("../debug.zig");
44const assert = debug.assert;
55const mem = @import("../mem.zig");
6const fmt = @import("../fmt.zig");
6const fmt = @import("../fmt/index.zig");
77const Allocator = mem.Allocator;
88const os = @import("index.zig");
99const math = @import("../math.zig");
std/rand.zig+1-1
......@@ -1,7 +1,7 @@
11const assert = @import("debug.zig").assert;
22const rand_test = @import("rand_test.zig");
33const mem = @import("mem.zig");
4const math = @import("math.zig");
4const math = @import("math/index.zig");
55
66pub const MT19937_32 = MersenneTwister(
77 u32, 624, 397, 31,
std/sort.zig+1-1
......@@ -1,6 +1,6 @@
11const assert = @import("debug.zig").assert;
22const mem = @import("mem.zig");
3const math = @import("math.zig");
3const math = @import("math/index.zig");
44
55pub const Cmp = math.Cmp;
66
test/behavior.zig+1
......@@ -2,6 +2,7 @@ comptime {
22 _ = @import("cases/array.zig");
33 _ = @import("cases/asm.zig");
44 _ = @import("cases/atomics.zig");
5 _ = @import("cases/bitcast.zig");
56 _ = @import("cases/bool.zig");
67 _ = @import("cases/cast.zig");
78 _ = @import("cases/const_slice_child.zig");
test/cases/bitcast.zig created+14
......@@ -0,0 +1,14 @@
1const assert = @import("std").debug.assert;
2
3test "@bitCast i32 -> u32" {
4 testBitCast_i32_u32();
5 comptime testBitCast_i32_u32();
6}
7
8fn testBitCast_i32_u32() {
9 assert(conv(-1) == @maxValue(u32));
10 assert(conv2(@maxValue(u32)) == -1);
11}
12
13fn conv(x: i32) -> u32 { @bitCast(u32, x) }
14fn conv2(x: u32) -> i32 { @bitCast(i32, x) }