Non-decimal radices/Input: Difference between revisions

Line 666:
<syntaxhighlight lang="javascript">parseInt("0e0"); // 0
parseInt("08"); // 0, '8' is not an octal digit.</syntaxhighlight></div>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq, and with fq.'''
 
Two filters are provided here for interpreting certain values as decimal numbers:
 
* `ibase($base)` interprets JSON integers and alphanumeric strings (possibly prefixed with one or more "-" signs) as numbers in the given base, and converts them to decimal integers;
* `ibase` also converts its inputs to decimal integers but recognizes the prefixes 0b 0o 0x in the conventional way.
 
In all cases:
* an input string can use any alphanumeric character with its conventional decimal value
** for example `"0bF" | ibase` evaluates to 15, even though "F" is not a binary digit;
* leading and trailing blanks are ignored;
* each leading "-" sign is interpreted as specifying the negative,
** for example: `"--1" | ibase` evaluates to 1;
* `"" | ibase` evaluates to null, and `"-"|ibase` raises an error;
* both filters accept certain JSON numbers in general.
 
<syntaxhighlight lang=jq>
# ibase($base) interprets its input as a number in base $base, and emits the
# corresponding decimal value. $base may be any positive integer.
#
# If the input is a JSON number, and the $base is 10, then the input is simply echoed.
# Otherwise, the input should be a JSON integer or an alphanumeric
# string optionally preceded by one or more occurrences of "-", and
# optionally surrounded by blanks.
# Examples: `"A"|base(2)` => 10
#
def ibase($base):
def tod: if 48 <= . and . <= 57 then . - 48 # 0-9
elif 65 <= . and . <= 90 then . - 55 # A-Z
elif 97 <= . and . <= 122 then . - 87 # a-z
else "ibase cannot handle codepoint \(.)" | error
end;
if type == "number" and $base==10 then .
else
tostring
| sub("^ *";"") | sub(" *$";"") | sub("^0*";"")
| if startswith("-") then - (.[1:] | ibase($base))
else
reduce (tostring|explode|reverse[]) as $point ({value: null, p: 1};
.value += ($point|tod) * .p
| .p *= $base)
| .value
end
end;
 
# After stripping off leading spaces and then leading "-" signs,
# infer the base from the input string as follows:
# prefix 0b for base 2, 0o for base 8, 0x for base 16,
# otherwise base 10
def ibase:
if type=="number" then .
else capture("^ *(?<signs>-*)(?<x>[^ ]*) *$") as $in
| $in.x
| if . == null then null
else (if startswith("0b") then .[2:] | ibase(2)
elif startswith("0o") then .[2:] | ibase(8)
elif startswith("0x") then .[2:] | ibase(16)
else ibase(10)
end) as $y
| if ($in.signs | length) % 2 == 0 then $y else - $y end
end
end;
</syntaxhighlight>
'''Examples'''
 
If your implementation of jq does not support $__loc__ then please adjust the def of assert accordingly.
<syntaxhighlight lang=jq>
# Assertions:
def assert($x; $y):
if ($x == $y) then empty
else "WARNING @ \($__loc__.line): \($x) != \($y)" | stderr, false
end;
def assertions:
assert("" | ibase; null),
assert("--1" | ibase; 1),
assert("11" | ibase(2); 3),
assert(11 | ibase(3); 4),
assert(11 | ibase(14); 15),
assert(" 0xF" | ibase; 15),
assert(" F" | ibase; 15),
assert("17" | ibase(8); 15),
assert("0o17" | ibase; 15),
assert(021 | ibase(7); 15),
assert("015" | ibase(10); 15),
assert(" 0bF "| ibase; 15),
assert("0b1111" | ibase; 15)
;
 
assertions
</syntaxhighlight>
{{output}}
Nada, as expected.
 
=={{header|Julia}}==
2,442

edits