parseInt() doesn't regard leading zeros, even with radix - javascript

When I want to convert a binary string to a base 10 decimal (Like this: parseInt('0001010', 2)), Javascript returns a decimal number, but a version in which the leading zeros mentioned in the example above have been disregarded. Is there any way to fix this?

So supposing you have the number '00000101101101':
var number = '00000101101101';
var length = number.length;
var decimal_number = parseInt(number, 2);
// going back
var new_number = decimal_number.toString(2);
var new_length = new_number.length;
var n_zeros = length - new_length;
var zeros = (n_zeros >= 2 ? Array(n_zeros+1).join("0") : "0");
new_number = zeros + new_number;

The decimal representation has no way to keep track of leading zeros. If you wish to keep the leading zeros in the result, you need a fundamentally different approach (e.g. keeping the output as a string).
Alternatively, if you know the width of the result a priori, you could just pad it with leading zeros on output.

Related

Javascript: how to get micronumbers in decimal format

I have simple function that calculates number of decimals,
eg. _d(0.01) = 2, _d(0.001) = 3 and so on.
We added some new coins to our system that have 0.00000001 quantity and function broke.
Here is why:
0.00000001.toString() = 1e-8, so I cant split it it by '.' and calculate length of second part as I did before.
So the question is - how to get string '0.00000001' out of 0.00000001 number easiest way.
EDIT
I didnt mean exactly '0.00000001', I meant any micronumber to decimal without exp. Some function _d(x) that would work _d(0.000000000012) = '0.000000000012'and so on. What usually toString() does to large (but not too large) numbers.
Use toFixed() with a large number of digits, then count the number of zeroes after the decimal point.
function _d(num) {
var str = num.toFixed(100);
var fraction = str.split('.')[1];
var zeros = fraction.match(/^0*/)[0].length;
return zeros + 1;
}
console.log(_d(0.1));
console.log(_d(0.01));
console.log(_d(0.000000001));
Do you want some thing like this
function decimalPlaces(num) {
var match = (''+num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
if (!match) { return 0; }
return Math.max(
0,
// Number of digits right of decimal point.
(match[1] ? match[1].length : 0)
// Adjust for scientific notation.
- (match[2] ? +match[2] : 0));
}
console.log(decimalPlaces(0.000000001))
First off, I got some inspiration for this answer from here:
How to avoid scientific notation for large numbers in JavaScript?
You can convert the number to a strong and then check for str.indexOf("e"). If true, then just return the scientific notation part of the string. For example:
function _d() {
// your current function here
if (str.indexOf("e")) {
var something = str.split("-")[1];
return something;
}
}
EDIT: I was working on this before your last comment to me, so this returns a string of the number, which I thought was what you wanted.
Leaving aside the point about significant digits, which is meaningful and correct but does not solve your problem, try this. We take the number, convert to string, if that string is not scientific notation then the answer is trivial. If it is scientific notation, then split the string twice (once on "e-" and then split the zeroth array on "." Add str[1]-1 zeroes to the lead of the number and add the digits to the end.
function _d(arg) {
var str = arg.toString();
if (str.indexOf("e-")) {
var digits = str.split("e-")[0];
var zeroes = str.split("e-")[1];
var zero = Number(zeroes);
var each = digits.split(".");
var something = "0.";
for (var i = 0; i < zeroes-1; i++) {
something += "0";
}
for (var j = 0; j < each.length; j++) {
something = something + each[j];
}
return something;
}
}
This won't work with very large numbers or very small negative numbers. And its pretty convoluted.
The other way is to use .toString() and then look for .length-2(2 characters - '0.'. It should give you the number of zeros.
The advantage of this method is you don't need to know the number of maximum decimals in the number.
To keep it as the full decimal:
Number(0.000001)
// 0.000001
To show it as a string:
0.000001.toFixed(6)
// "0.000001"

Javascript split integer and add decimal point

My integer value is 1210 and i want split this integer like 1 | 210 .Have to add decimal point on middle.
Eg:
var integer=1210;
Split this integer and add decimal value like this 1.210
Why don't you just divide the number by 1000
var x = 1210;
var y = 1210/1000; //1.210 number
var z = y+""; // 1.120 will be string here
console.log(y); // Will output 1.210
If you're always dealing with 4 digit numbers, dividing by 1000 will work (as mentioned in another answer) but you'll need to use toFixed to make sure javascript doesn't remove trailing zeros:
var x = 1210;
(x / 1000).toFixed(3) // => "1.210"
(x / 1000) + "" // => "1.21"
More generically you could use:
x=prompt('enter an integer');
xl=x.toString().length-1
alert((x/Math.pow(10,xl)).toFixed(xl));
(just make sure you enter an integer, preferably +ve, at the prompt)

Javascript: Convert a string representation of money to Number

Lets say I have an amount in string format like this:
amount = '12,000.00'
I want to convert it into a Number (Javascript) or a float.
parseFloat(amount) // this gives me 12 as a result
Number(amount) // this gives me NaN as a result
Other solution I thought was this:
parseFloat(amount.replace(/[,]/g, ''))
This works fine. But the problem here is the Locale.
This would fail when the amount is € 12000,00.
Here ',' has altogether a different meaning.
I looked around for a good solution but couldn't. I am looking for a generalized solution.
This is not that easy, as you can't exactly know what's the delimiter for thousands and what for the decimal part
Consider "12.000.000" is it 12000.000 === 12000 or 12000000?
But if you would set the requirement that the last delimiter is always the decimal delimiter -
meaning if at least one delimiter is given, the last one has to be the decimal delimiter, *if the digits following, don't exceed a defined length.
Then you could try the following
Edit
(see the revs if you're interested in the old function)
I put in the ability to define the max length of digits after the last delimiter "," or "." up until it is treated as float, after that its returned as integer
var amounts = ["12000","12.000,00", "12,000.00", "12,000,01", "12.000.02", "12,000,001"];
formatMoney.maxDecLength = 3; //Set to Infinity o.s. to disable it
function formatMoney(a) {
var nums = a.split(/[,\.]/);
var ret = [nums.slice(0, nums.length - 1).join("")];
if (nums.length < 2) return +nums[0];
ret.push(nums[nums.length - 1]);
return +(ret.join(nums[nums.length - 1].length < formatMoney.maxDecLength ? "." : ""));
}
for ( var i=0,j;j=amounts[i];i++)
console.log (j + " -> " +formatMoney(j));
Gives the output:
"12000 -> 12000"
"12.000,00 -> 12000"
"12,000.00 -> 12000"
"12,000,01 -> 12000.01"
"12.000.02 -> 12000.02"
"12,000,001 -> 12000001" //as you can see after the last "," there are 3 digits and its treated as integer
Another JSBin
You can get the local decimal delimiter in this manner:
1.1.toLocaleString().substr(1,1)
Before parse float, you could make sure the string contains nothing but numbers, possibly a minus sign, and the local decimal delimiter.
The truth is, you'll never know the format. 12,345. Is that 12345, or another locale version if 12.345?
However, if you have consistent decimals, then you'd be able to use the lastIndexOf function on a comma and a period will reveal the decimal position and character.
var price = '12,345.67';
var lastPeriod = price.lastIndexOf('.');
var lastComma = price.lastIndexOf(',');
if (lastComma != -1 && lastComma > lastPeriod) {
decimalCharacter = ',';
} else {
decimalCharacter = '.';
}
console.log(decimalCharacter); //. or , based on how the price string looks - see below
If price is 12,345.67, decimalCharacter will be .. If it's 12.345,67, it'll be returned as ,.

Truncate decimal number (as strings) to a fixed number of places

I want to truncate numbers (given as strings) to a fixed number of decimal places. The numbers can be negative (with a minus sign), positive (no sign). I'd prefer to round the numbers properly and keep trailing zeroes. I want the same number of decimal places, no matter how long the whole number is. The numbers will be stored back as strings.
For example:
140.234234234 -> 140.234
1.123123 -> 1.123
-12.789789 -> -12.790
First parse them as floats, then format with toFixed:
var nums = [
"140.234234234", // -> 140.234
"1.123123", // -> 1.123
"-12.789789" // -> -12.790
];
nums.forEach(function(n) {
console.log(parseFloat(n).toFixed(3));
});
http://codepen.io/anon/pen/IvxmA
Any number can be displayed as a fixed decimal place string by using .toFixed:
var num = 140.234234234;
var fixedDecimalPlace = num.toFixed(3); // is "140.234"
function truncate( numberString, trunk ) {
var onpoint = numberString.split('.',2);
var numberStringTruncated = numberString;
if (onpoint.length > 1) {
numberStringTruncated = onpoint[0] + '.' + onpoint[1].substring(0,trunk);
}
return numberStringTruncated;
}
This does not consider rounding or padding. As the other answer suggested, you should use parseFloat followed by toFixed

Compressing a Hex String in JavaScript/NodeJS

My app generates links, which contain hex string like: 37c1fbcabbc31f2f8d2ad31ceb91cd8d0d189ca5963dc6d353188d3d5e75b8b3e401d4e74e9b3e02efbff0792cda5c4620cb3b1f84aeb47b8d2225cd40e761a5. I would really like to make them shorter, like the solution mentioned for Ruby in Compressing a hex string in Ruby/Rails.
Is there a way to do this in JavaScript/NodeJS?
node int-encoder does this, using the strategy already mentioned.
it also supports large numbers
npm install int-encoder
var en = require('int-encoder');
//simple integer conversion
en.encode(12345678); // "ZXP0"
en.decode('ZXP0'); // 12345678
//convert big hex number using optional base argument
en.encode('e6c6b53d3c8160b22dad35a0f705ec09', 16); // 'hbDcW9aE89tzLYjDgyzajJ'
en.decode('hbDcW9aE89tzLYjDgyzajJ', 16); // 'e6c6b53d3c8160b22dad35a0f705ec09'
You could use toString and parseInt method, that basically are doing the same thing of the methods you mentioned in the link:
var hexString = "4b3fc1400";
var b36 = parseInt(hexString, 16).toString(36); // "9a29mgw"
And to convert it back, you just need to do the opposite:
hexString = parseInt(b36, 36).toString(16); // "4b3fc1400"
The only problem with your string, is that is too big to be threat as number in JavaScript. You should split them in chunk. JavaScript's numbers are accurate up to 2^53 (plus sign), so the max positive number you can handle is 0x20000000000000 (in hexadecimal, that is 9007199254740992 in decimal); you can use the accuracy to handle the chunk:
var hexString = "37c1fbcabbc31f2f8d2ad31ceb91cd8d0d189ca5963dc6d353188d3d5e75b8b3e401d4e74e9b3e02efbff0792cda5c4620cb3b1f84aeb47b8d2225cd40e761a5"
var b36 = "", b16 = "";
var chunk, intChunk;
// 14 is the length of 0x20000000000000 (2^53 in base 16)
for (var i = 0, max = 14; i < hexString.length; i += max) {
chunk = hexString.substr(i, max);
intChunk = parseInt(chunk, 16);
if (intChunk.toString(16) !== chunk) {
intChunk = parseInt(hexString.substr(i, max - 1), 16);
i -= 1;
}
b36 += intChunk.toString(36)
}
// 11 is the length of 2gosa7pa2gv (2^53 in base 36)
for (var i = 0, max = 11; i < b36.length; i += max ) {
chunk = b36.substr(i, max);
intChunk = parseInt(chunk, 36);
if (intChunk.toString(36) !== chunk) {
intChunk = parseInt(b36.substr(i, max - 1), 36);
i -= 1;
}
b16 += intChunk.toString(16)
}
console.log(hexString);
console.log(b36);
console.log(b16);
Update: You could also use a base 62 instead of 36 to compress more, but notice that JS supports up to base 36, so you need to implement that personal notation manually (I believe there are already some implementation around).
The simplest and fastest thing to do is define a set of 64 safe characters for use in the URL, such as A-Z, a-z, 0-9, _, and $. Then encode every three hex digits (4 bits each) into two safe characters (6 bits each). This requires no multiplication and division, and it can be used on arbitrarily long strings.
You will need to pick a 65th character to use at the end of the string to indicate if the last four-bit piece is used or not. Otherwise you will have an ambiguity for character strings with an even number of characters. Let's call it 2n. Then there are either 3n-1 or 3n hex digits encoded within, but there is no way to tell which. You can follow the sequence with a special character to indicate one of those cases. E.g. a '.' (period).
Note: The last few characters picked here for the set differ from Base64 encoding, since URLs have their own definition of safe punctuation characters. See RFC 1738.

Categories

Resources