Module:Radix: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
rejigger this thing to work with negative b |
||
| Line 2: | Line 2: | ||
r.decimal_to = function(frame) | r.decimal_to = function(frame) | ||
-- Get | -- Get number (in base 10) | ||
decimal = tonumber(frame.args[1]) | |||
-- If decimal is 0 or 1, return decimal | |||
if decimal == 0 or decimal == 1 then | |||
return tostring(decimal) | |||
end | |||
-- Do I use separators? | |||
format_output = format_output and format_output or true | format_output = format_output and format_output or true | ||
-- Get radix to convert to | |||
radix = tonumber(frame.args[2]) | |||
-- If | -- sign is equal to sign(decimal) if radix is positive, and 1 otherwise | ||
if | sign = radix > 0 and decimal / math.abs(decimal) or 1 | ||
-- If radix is not an integer: Round to nearest integer for now | |||
radix = radix < 0 and math.ceil(x) or math.floor(x) | |||
-- If abs(radix) is 1, 0, or > 36, return decimal | |||
if radix == 0 or math.abs(radix) == 1 or math.abs(radix) > 36 then | |||
return tostring(decimal) | return tostring(decimal) | ||
end | end | ||
-- | |||
-- characters are based on other proglangs' parsing | |||
characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |||
-- precision is the number of digits below 1 to use | -- precision is the number of digits below 1 to use | ||
-- if decimal is less than 1/newradix ^ precision, return 0 | -- if decimal is less than 1/newradix ^ precision, return 0 | ||
precision = tonumber(frame.args[3]) or 0 | |||
minpower = newradix ^ (precision * -1) | |||
if decimal < minpower then | if decimal < minpower then | ||
return "0" | return "0" | ||
end | end | ||
-- | -- arrays of digits | ||
digits = {} | |||
digitchars = {} | |||
-- | -- maxpower calculation | ||
maxpower = 1 | |||
while math.abs(maxpower) < math.abs(decimal) do | |||
maxpower = maxpower * radix | |||
end | |||
-- if decimal < 0 then maxpower should be 1 | |||
-- calculate digits | |||
if | digitval = maxpower | ||
i = 1 | |||
-- format radix and set up num of integral digits for possible formatting | |||
if radix > 0 then decimal = math.abs(decimal) end | |||
integrals = 0 | |||
while math.abs(digitval) >= math.abs(minpower) do | |||
-- get floor of abs(decimal) / abs (digitval) | |||
thisdigit = math.floor(math.abs(decimal) / math.abs(digitval)) | |||
-- if i is 1 and thisdigit is 0: | |||
-- if radix is negative, add 1 to thisdigit | |||
-- if radix is positive and maxpower isn't 1, skip | |||
add_digit = true | |||
if thisdigit == 0 and i == 1 then | |||
if radix < 0 then | |||
thisdigit = 1 | |||
elseif maxpower > 1 then | |||
add_digit = false | |||
end | |||
end | |||
if add_digit then | |||
-- add thisdigit to digits | |||
digits[i] = thisdigit | |||
-- subtract thisdigit * digitval from decimal | |||
decimal = decimal - (thisdigit * digitval) | |||
if digitval >= 1 then integrals = integrals + 1 end | |||
digitval = digitval / radix | |||
i = i + 1 | |||
end | |||
end | end | ||
-- assemble digits | |||
separators = 0 | |||
distance = math.abs(radix) <= 6 and 3 or 4 | |||
for j,digit in ipairs(digits) do | |||
digitchars[j+separators] = string.sub(characters, digit+1, digit+1) | |||
-- when integrals - j is a positive multiple of distance | |||
if format_output then | |||
if j < integrals and (integrals - j) % distance == 0 then | |||
-- add "," and 1 to separators | |||
separators = separators + 1 | |||
digitchars[j+separators] = "," | |||
end | |||
end | |||
-- when j equals integrals | |||
if j == integrals then | |||
-- add "." and 1 to separators | |||
separators = separators + 1 | |||
digitchars[j+separators] = "." | |||
end | end | ||
end | end | ||
-- if sign is -1, append a negative sign to the front | |||
signchar = sign == -1 and "" or "-" | |||
ret = "" .. signchar | |||
-- assemble final number | |||
for k,character in ipairs(digitchars) do | |||
ret = ret .. character | |||
end | |||
end | end | ||
return r | return r | ||
Revision as of 18:51, 5 July 2026
Documentation for this module may be created at Module:Radix/doc
local r = {}
r.decimal_to = function(frame)
-- Get number (in base 10)
decimal = tonumber(frame.args[1])
-- If decimal is 0 or 1, return decimal
if decimal == 0 or decimal == 1 then
return tostring(decimal)
end
-- Do I use separators?
format_output = format_output and format_output or true
-- Get radix to convert to
radix = tonumber(frame.args[2])
-- sign is equal to sign(decimal) if radix is positive, and 1 otherwise
sign = radix > 0 and decimal / math.abs(decimal) or 1
-- If radix is not an integer: Round to nearest integer for now
radix = radix < 0 and math.ceil(x) or math.floor(x)
-- If abs(radix) is 1, 0, or > 36, return decimal
if radix == 0 or math.abs(radix) == 1 or math.abs(radix) > 36 then
return tostring(decimal)
end
-- characters are based on other proglangs' parsing
characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-- precision is the number of digits below 1 to use
-- if decimal is less than 1/newradix ^ precision, return 0
precision = tonumber(frame.args[3]) or 0
minpower = newradix ^ (precision * -1)
if decimal < minpower then
return "0"
end
-- arrays of digits
digits = {}
digitchars = {}
-- maxpower calculation
maxpower = 1
while math.abs(maxpower) < math.abs(decimal) do
maxpower = maxpower * radix
end
-- if decimal < 0 then maxpower should be 1
-- calculate digits
digitval = maxpower
i = 1
-- format radix and set up num of integral digits for possible formatting
if radix > 0 then decimal = math.abs(decimal) end
integrals = 0
while math.abs(digitval) >= math.abs(minpower) do
-- get floor of abs(decimal) / abs (digitval)
thisdigit = math.floor(math.abs(decimal) / math.abs(digitval))
-- if i is 1 and thisdigit is 0:
-- if radix is negative, add 1 to thisdigit
-- if radix is positive and maxpower isn't 1, skip
add_digit = true
if thisdigit == 0 and i == 1 then
if radix < 0 then
thisdigit = 1
elseif maxpower > 1 then
add_digit = false
end
end
if add_digit then
-- add thisdigit to digits
digits[i] = thisdigit
-- subtract thisdigit * digitval from decimal
decimal = decimal - (thisdigit * digitval)
if digitval >= 1 then integrals = integrals + 1 end
digitval = digitval / radix
i = i + 1
end
end
-- assemble digits
separators = 0
distance = math.abs(radix) <= 6 and 3 or 4
for j,digit in ipairs(digits) do
digitchars[j+separators] = string.sub(characters, digit+1, digit+1)
-- when integrals - j is a positive multiple of distance
if format_output then
if j < integrals and (integrals - j) % distance == 0 then
-- add "," and 1 to separators
separators = separators + 1
digitchars[j+separators] = ","
end
end
-- when j equals integrals
if j == integrals then
-- add "." and 1 to separators
separators = separators + 1
digitchars[j+separators] = "."
end
end
-- if sign is -1, append a negative sign to the front
signchar = sign == -1 and "" or "-"
ret = "" .. signchar
-- assemble final number
for k,character in ipairs(digitchars) do
ret = ret .. character
end
end
return r