Skip to content

Instantly share code, notes, and snippets.

@getify
Last active November 17, 2015 00:54
Show Gist options
  • Save getify/e5ed084f122d73ac375b to your computer and use it in GitHub Desktop.
Save getify/e5ed084f122d73ac375b to your computer and use it in GitHub Desktop.
var hex_source = ["2", "4", "3", "F", "6", "A", "8", "8", "8", "5", "A", "3", "0", "8", "D", "3", "1", "3", "1", "9"],
decimal_digits = [], holding = [];
function pumpNextHex(source) {
var digit = parseInt(source.shift(),16), new_digits;
holding.push(digit);
// carry-over upward
for (var idx=holding.length-1; idx>0; idx--) {
if (holding[idx] > 9) {
holding[idx-1]++;
holding[idx] = 9;
}
else break;
}
// roll off "finished" decimal digits up to `idx-1`
if (idx > 0) {
new_digits = holding.slice(0,idx);
holding = holding.slice(idx);
decimal_digits = decimal_digits.concat(new_digits);
return new_digits.length;
}
return 0;
}
// "2" -->
pumpNextHex(hex_source); // 0 -- good!
decimal_digits; // [] -- good!
// "4" -->
pumpNextHex(hex_source); // 1 -- good!
decimal_digits; // [2] -- no! should be [1] as in 14159...
// "3" -->
pumpNextHex(hex_source); // 1 -- good!
decimal_digits; // [2,4] -- no! should be [1,4]
// "F" -->
pumpNextHex(hex_source); // 0 -- good!
decimal_digits; // [2,4] -- should still be [1,4]
// "6" -->
pumpNextHex(hex_source); // 2 -- good!
decimal_digits; // [2,4,4,9] -- no! should be [1,4,1,5]
@mwhipple
Copy link

you're missing something that would explain how 2,4,3,.. -> 1,4,1,... If this were just decimal digits encoded into hexadecimal then the only time the encoding would matter would be A-F and so 2,4,3 would never be able to be anything other than 2,4,3 unless you carry backwards which would lead to 2,4,4 which is still far away from 1,4,1. This assumes that each point after the decimal point represents 1/(10^n) (=10^{-n}), 1/10, 1/100, etc so you're fitting a base 16 number into a base 10 bucket which doesn't buy much.

If the whole number is hexadecimal then all of the buckets should have 16 possible values and everything after the hexadecimal point corresponds to 16^{-n}: 1/16, 1/256, etc. Each digit has more precision and is more computer friendly since it can be readily represented in binary (avoiding typical floating point rounding issues) and can use some under-the-hood optimizations like bit wise shifting. 2/16 + 4/256 = .140625 which gives the first 2 digits, the overflow adds additional precision and carries forwards through the array rather than backwards: the above would leave ...0625 which would be added to 3/4096 to yield the 1 for the next digit.

Floating point should be fine because of the hex numbers, but integers could also be used either by shifting the decimal point around or using 625 since 1/16 is .0625 (or a more rigorous explanation around (10/2)^4) and adjusting the decimal points appropriately

Copy link

ghost commented Nov 15, 2015

var hex_source = ["2", "4", "3", "F", "6", "A", "8", "8", "8", "5", "A", "3", "0", "8", "D", "3", "1", "3", "1", "9"],
      decimal_digits = [], holding = 0, indx = 0

function pumpNextHex(source) {
    var dec = parseInt(source.shift(),16)/Math.pow(16,indx+1) * Math.pow(10,indx+1); 
    dec = dec + holding; 
    whole = Math.floor(dec);
    holding = (dec % 1) *10;
    indx ++;
    decimal_digits.push(whole);
    return decimal_digits
}

@yelouafi
Copy link

var BigNumber = require('bignumber.js');
x = new BigNumber('3.243F6A8885A308D31319',16)
console.log(x.toPrecision(10));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment