From 97595c4b50c38668b1588180664421d55c5b298c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 23 Jan 2023 14:00:02 +0000 Subject: [PATCH] Use a LUT for `shift_left` --- core/strconv/decimal/decimal.odin | 142 +++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 21 deletions(-) diff --git a/core/strconv/decimal/decimal.odin b/core/strconv/decimal/decimal.odin index 03fde3012..24ad2ce91 100644 --- a/core/strconv/decimal/decimal.odin +++ b/core/strconv/decimal/decimal.odin @@ -214,25 +214,128 @@ shift_right :: proc(a: ^Decimal, k: uint) { trim(a) } -shift_left :: proc(a: ^Decimal, k: uint) { - // NOTE(bill): used to determine buffer size required for the decimal from the binary shift - // 'k' means `1< bool #no_bounds_check { + for i in 0..= len(b) { + return true + } + if b[i] != s[i] { + return b[i] < s[i] + } + } + return false + } + + assert(k < 61) + + delta := _shift_left_offsets[k].delta + if prefix_less(a.digits[:a.count], _shift_left_offsets[k].cutoff) { + delta -= 1 + } + + read_index := a.count + write_index := a.count+delta n: uint - for r -= 1; r >= 0; r -= 1 { - n += (uint(a.digits[r]) - '0') << k + for read_index -= 1; read_index >= 0; read_index -= 1 { + n += (uint(a.digits[read_index]) - '0') << k quo := n/10 rem := n - 10*quo - w -= 1 - if w < d { - a.digits[w] = byte('0' + rem) + write_index -= 1 + if write_index < len(a.digits) { + a.digits[write_index] = byte('0' + rem) } else if rem != 0 { a.trunc = true } @@ -242,21 +345,18 @@ shift_left :: proc(a: ^Decimal, k: uint) { for n > 0 { quo := n/10 rem := n - 10*quo - w -= 1 - if w < d { - a.digits[w] = byte('0' + rem) + write_index -= 1 + if write_index < len(a.digits) { + a.digits[write_index] = byte('0' + rem) } else if rem != 0 { a.trunc = true } n = quo } - // NOTE(bill): Remove unused buffer size - assert(w >= 0) - capacity -= w + a.decimal_point += delta - a.count = min(a.count+capacity, d) - a.decimal_point += capacity + a.count = clamp(a.count, 0, len(a.digits)) trim(a) }