Prev: FAQ Topic - How do I open a new window with javascript? (2010-06-30)
Next: How to trigger two events with 2 document.locations?
From: pete on 1 Jul 2010 05:11 On Jun 30, 3:25 pm, Ken Snyder <kendsny...(a)gmail.com> wrote: I must be missing something. What is that subtle something? > (5).toString(2); // "101" > (16).toString(2); // "10000" As I read it, the OP wants to go FROM string, not toString( ). Thus: function toBin(n) { return + n; } straight from the FAQ, should work, should it not? [ http://www.jibbering.com/faq/notes/type-conversion/#tcParse ] -- pete
From: pete on 1 Jul 2010 07:58 On Jul 1, 5:11 am, pete <pete...(a)yahoo.com> wrote: > I must be missing something. What is that subtle something? Answering my own question, that "subtle something" is: > real code works with integer strings of any length as the OP specified early, whereas my suggested solution ( binVal = + stringVal ) only works for strings of max 10 digits, and fewer than half of those. Sorry for missing the OP's crucial stipulation. -- pete
From: Scott Sauyet on 1 Jul 2010 12:44 On Jun 30, 11:12 am, RobG <rg...(a)iinet.net.au> wrote: > I'm working on a function to convert decimal integers to binary. The > version below is an example of my implementation of a halving > algorithm, real code works with integer strings of any length and > handles sign. I've reduced the functionality a bit so I don't have to > post the supporting functions for large ints. > > This one only works within the range of values supported by the > ECMAScript implementation it's running in and with unsigned integers > (don't use numbers larger than 9 digits). This version works with arbitrary length ints, that is on strings containing nothing but decimal digits: var toBin = (function() { var digitHalves = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4], remainderHalves = [5, 5, 6, 6, 7, 7, 8, 8, 9, 9]; return function(digits) { digits = digits.split(""); var binDigits = []; while (digits.length) { var ptr = 0, digit = 0; while (digits[0] == '0') digits.shift(); while (ptr < digits.length) { var carry = digit digit = digits[ptr] % 2; digits[ptr] = carry ? remainderHalves[digits[ptr]] : digitHalves[digits[ptr]]; ptr++; } binDigits.push(digit); } binDigits.reverse().shift(); return binDigits.join("");; }; }()); I have not tested performance. It's performing division digit-by- digit, via lookups, so I wouldn't be surprised if it's slow. But it seems to be straightforward. The two lookups, digitHalves and remainderHalves respectively return half of the current digit and half of ten more than the current digit, in either case rounded down to the nearest digit. It does avoid a division... -- Scott
From: Stefan Weiss on 1 Jul 2010 13:34 On 01/07/10 18:44, Scott Sauyet wrote: > On Jun 30, 11:12 am, RobG <rg...(a)iinet.net.au> wrote: >> I'm working on a function to convert decimal integers to binary. The >> version below is an example of my implementation of a halving >> algorithm, real code works with integer strings of any length and >> handles sign. I've reduced the functionality a bit so I don't have to >> post the supporting functions for large ints. >> >> This one only works within the range of values supported by the >> ECMAScript implementation it's running in and with unsigned integers >> (don't use numbers larger than 9 digits). I didn't quite understand the point of your function. Either you're doing arbitrary precision math, which means you can't treat the input string as a number - or - you're restricting yourself to integers in the usual supported range, which means you can perform normal math operations on the string, but then you could just as well just use toString(2). > This version works with arbitrary length ints, that is on strings > containing nothing but decimal digits: Damn, beat me to it :) > var toBin = (function() { > var digitHalves = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4], > remainderHalves = [5, 5, 6, 6, 7, 7, 8, 8, 9, 9]; > return function(digits) { > digits = digits.split(""); > var binDigits = []; > while (digits.length) { > var ptr = 0, digit = 0; > while (digits[0] == '0') digits.shift(); > while (ptr < digits.length) { > var carry = digit > digit = digits[ptr] % 2; > digits[ptr] = carry ? remainderHalves[digits[ptr]] > : digitHalves[digits[ptr]]; > ptr++; > } > binDigits.push(digit); > } > binDigits.reverse().shift(); > return binDigits.join("");; > }; > }()); > > I have not tested performance. It's performing division digit-by- > digit, via lookups, so I wouldn't be surprised if it's slow. But it > seems to be straightforward. The two lookups, digitHalves and > remainderHalves respectively return half of the current digit and half > of ten more than the current digit, in either case rounded down to the > nearest digit. It does avoid a division... Interesting, I didn't think of that. Here's my attempt: function toBin (numStr) { var bigInt = numStr.split(""), len = bigInt.length, result = [], rem, digit, i; do { for (rem = i = 0; i < len; ++i) { digit = +bigInt[i] + rem * 10, rem = digit & 1, bigInt[i] = (digit - rem) / 2; // or (digit / 2) | 0 } if (!bigInt[0]) { bigInt.shift(); --len; } result.push(rem); } while (len); return result.reverse().join(""); } It's a pretty naive implementation of a normal short division. I'm sure there are more efficient ways to do it, but I thought looking them up would be cheating. Performance appears more or less comparable. The only difference in the results I've seen is that yours returns an empty string for "0" ;-) -- stefan
From: Stefan Weiss on 1 Jul 2010 13:36
On 01/07/10 19:34, Stefan Weiss wrote: > digit = +bigInt[i] + rem * 10, > rem = digit & 1, > bigInt[i] = (digit - rem) / 2; // or (digit / 2) | 0 Whoops, those were suposed to be statements. I must have missed that during refactoring. -- stefan |