Created
September 19, 2016 17:59
-
-
Save marcin-chwedczuk/5d6f0c4c2bc9f40370d241fc529724e4 to your computer and use it in GitHub Desktop.
Compute 116 000 digits of e using Steve Wozniak algorithm from Byte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// see: https://archive.org/stream/byte-magazine-1981-06/1981_06_BYTE_06-06_Operating_Systems#page/n393/mode/2up | |
function word(x) { return (x & 0xffff); } | |
function wordstr(x) { return ('0000000000000000' + x.toString(16)).slice(-4); } | |
function divide(dividendWords, divisorWord, prevRest) { | |
var BITS_PER_WORD = 16; | |
var MAX_DIVISOR = (1 << 16) - 1; | |
if (divisorWord > MAX_DIVISOR) | |
throw new Error('divisor too large.'); | |
var d = divisorWord; | |
var hi = +(prevRest || 0); | |
var lo = 0; | |
for (var w = 0, len = dividendWords.length; w < len; w++) { | |
lo = dividendWords[w]; | |
// divide [hi|lo] by d | |
for (var i = 0; i < BITS_PER_WORD; i++) { | |
// hi <- MSB lo <- lo | |
var loMSB = (lo & (1 << 15)) >> 15; | |
hi = word(hi << 1 | loMSB); | |
var r = 0; | |
if (hi >= d) { | |
hi -= d; | |
r = 1; | |
} | |
// lo <- bit of result | |
lo = word(lo << 1) | r; | |
} | |
dividendWords[w] = lo; | |
} | |
// return rest | |
return hi; | |
} | |
function print10(words, digits) { | |
var str = '2.'; | |
var mult100 = [], carry100 = []; | |
for (var i = 0; i < 256; i++) { | |
var w = (i*100); | |
mult100[i] = w & 0x00ff; | |
carry100[i] = (w & 0xff00) >> 8; | |
} | |
var carry = 0; | |
var mult100Byte = function(b) { | |
var carryB = carry100[b]; | |
b = mult100[b] + carry; | |
carry = ((b & 0xff00) >> 8) + carryB; | |
b = (b & 0x00ff); | |
return b; | |
}; | |
for (var i = 0; i < digits; i+=2) { | |
// multiply words by 100 | |
for (var j = words.length-1; j >= 0; j--) { | |
var lo = mult100Byte(words[j] & 0x00ff); | |
var hi = mult100Byte((words[j] & 0xff00) >> 8); | |
words[j] = (hi << 8) | lo; | |
} | |
var digit0 = (carry % 10); | |
var digit1 = Math.floor(carry / 10) % 10; | |
str += String(digit1) + String(digit0); | |
} | |
console.log(str); | |
} | |
function calculateE(words, N) { | |
for (var n = N; n >= 2; n--) { | |
// console.log('[' + ((n*100/N)|0) + ']') | |
divide(words, n, 1); | |
} | |
} | |
function zeroArray(n) { | |
var a = []; | |
for (var i = 0; i < n; i++) | |
a[i] = 0; | |
return a; | |
} | |
var dividentFract = zeroArray(48*1024); | |
calculateE(dividentFract, 30000); | |
// prints 116 000 digits of e after . | |
print10(dividentFract, 116000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment