Problem
I need to return a number in the format of .66 (from an entered value which includes the leading zero, e.g. 0.66)
It must be returned as an integer with the decimal point as the first character.
what method in JavaScript can help me do this?
What have I tried?
I've tried converting it toString() and back to parseInt() but including the decimal point makes it return NaN.
I've tried adding various radix (10, 16) to my parseInt() - also unsuccessful
Sample Code
const value = 0.66;
if(value < 1) {
let str = value.toString().replace(/^0+/, '');
// correctly gets '.66'
return parseInt(str)
}
//result NaN
Expectations
I expect an output of the value with the leading 0 removed
e.g. 0.45 --> .45 or 0.879 --> .879
Current Observations
Output is NaN
I tried a quick solution, you may try to do this:
let a = 0.45;
// split on decimal, at index 1 you will find the number after decimal
let b = a.toString().split('.')[1];
Issue #1:
0.66 is not an Integer. An Integer is a whole number, this is a floating-point number.
Issue #2:
You cannot have a number in JavaScript that starts with a decimal point.
Even if you change your parseInt to be parseFloat, it will still return 0.66 as a result.
What you're asking just isn't possible, if you want a number to start with a decimal point then it has to be a string.
In JavaScript code where the 8 bits of a byte represent 8 Boolean "decisions" (aka: flags), there is a need to isolate each given bit for conversion to a Boolean variable. Consider my solution using String parsing:
var bitParser = function (_nTestByte, _nBitOrdinal) {
var bits = ("00000000" + _nTestByte.toString(2)).slice(-8); // convert to binary and zero-pad
return bits[_nBitOrdinal] === "1";
};
console.log(bitParser(0b10100101, 2)); // ECMAScript 6+ prefix, returns true
It works, and shows the desired result. However I have a hypothesis stating that a bit shifting technique would be a faster option than String manipulation. I tend to believe that but desire to prove it.
The problem is, I have yet to produce such a function that works correctly, let alone something I can test. I have created the following logic plan that I believe is accurate:
/*
LOGIC PLAN
----------
0) Remember: all bitwise operators return 32 bits even though we are using 8
1) Left shift until the desired bit is the left-most (highest) position;
2) Right shift (zero filling) 31 bits to eliminate all right bits
*/
The implementation of the login plan follows. Because of the 32 bit nature of bitwise operators, its my belief that the entire left 3 bytes (24 bits) must be shifted off first before we even reach the byte being worked on. Then, assuming a scenario where the 3rd bit from the left (String ordinal 2) is the desired bit, I am shifting off 2 more bits (ordinals 0 & 1), for a total of 26 bits of left shifting.
This should produce a binary number with the desired bit all the way left followed by 31 undesired zero bytes. Right shifting those 31 bits away produces a binary with 31 (now) leading zero bits which evaluates to whatever the value of the desired bit is. But of course, I would not be writing this question if THAT were true, now would I? :-)
// hardcoded, assuming the second "1" (ordinal 2) is the bit to be examined
console.log((0b10100101 << 26) >> 31); // instead of 1, returns -1
I feel like I am really close, but missing something or pushing JavaScript too hard (lol).
In JavaScript code where the 8 bits of a byte represent 8 Boolean "decisions" (aka: flags), there is a need to isolate each given bit for conversion to a Boolean variable...
If that's the actual goal, bitshifting is neither necessary nor useful: Just use a bitwise & with the desired bit, which will give you either 0 or a number with that bit set. 0 is falsy, the number with a bit set is truthy. You can either use that as-is, or force it to boolean via !!flag or Boolean(flag):
Here's your bitParser function using bitmasking:
var bitParser = function (_nTestByte, _nBitOrdinal) {
return !!(_nTestByte & Math.pow(2, _nBitOrdinal));
};
console.log(bitParser(0b10100101, 2)); // true
console.log(bitParser(0b10100101, 1)); // false
Rather than doing the Math.pow every time, of course, we'd probably be better off with a lookup table:
var bits = [
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000
];
var bitParser = function (_nTestByte, _nBitOrdinal) {
return !!(_nTestByte & bits[_nBitOrdinal]);
};
console.log(bitParser(0b10100101, 2)); // true
console.log(bitParser(0b10100101, 1)); // false
From your question I took
console.log((0b10100101 << 26) >> 31); //instead of 1, returns -1.
And to answer your question why it returned -1 instead of 1
You need to do unsigned right shift >>> instead of signed one >>
console.log((0b10100101 << 26 ) >>>31);
Yes it can, and what you're doing is almost correct.
Integers are represented as a 32bit binary number, with the leftmost bit representing the sign (it's 1 if the number is negative and 0 if the number is positive). Lets look at some of the numbers' representations:
//last 31 digits keeps increasing as the number decreases
// ...
-2 => 0b11111111111111111111111111111110
-1 => 0b11111111111111111111111111111111
0 => 0b00000000000000000000000000000000
1 => 0b00000000000000000000000000000001
2 => 0b00000000000000000000000000000010
// ...
// last 31 digits keep increasing as the number increases
Now, what you're having (0b10100101 << 26) should give you 10010100000000000000000000000000, which you'd expect to be a big negative number (because the left-most bit is 1). Then right afterwards, you have >> 31 which you're expecting to strip off all 31 bits and leave you with the left-most bit.
That should work, but it's not what's happening. And why is that? It's because the people who came up with ECMAScript thought it would make more sense if 4 >> 1 returns 2 and -4 >> 1 returns -2.
4 >> 1 // returns 2 which is 0b00000000000000000000000000000010
0b0000000000000000000000000000000100 >> 1 // returns 2, same
-4 >> 1 // returns -2, which is 0b11111111111111111111111111111110
But -4 is 0b11111111111111111111111111111100, and for your purposes right shifting it by 1 should yield 0b01111111111111111111111111111110 (big positive number, since left-post bit is 0), and that's not -2!
To overcome that, you can use the other right shift operator which doesn't care about about the sign: >>>. -4 >>> 1 is 2147483646 which is what we want.
So console.log((0b10100101 << 26) >>> 31); gives you 1, which is what you want. You can also keep using >> and regarding any negative outcome to be a result of 1 being the chosen bit.
The most simple way to achieve your actual need is to use simple conditions rather than trying to isolate bits.
var bitParser = function (_nTestByte, _nBitOrdinal) {
return (_nTestByte & _nBitOrdinal);
};
console.log(bitParser(6, 2) ? true : false); // true
console.log(bitParser(6, 1) ? true : false); // false
I adapted the console.log() expression in a way that may seem complicated.
It's only to really show the logical result at this step, while I didn't choose to use !! inside of the function, so returning a truly/falsy value rather than true|false.
Actually this way keeps all the most simple possible, because the expected use else where in the code is if (bitParser(...)), which automatically casts the result to boolean.
BTW, this works whatever is the _nTestByte size (may be more than 1 byte).
I have objects in array:
x[{a=2.99, b=5.11}{a=4.99, b=2.11}]
And I want it to display 1 decimal with Math round, as I use Math.round(x[0].a*10)/10; it displays 3, while it works fine if I use just numbers as Math.round(2.99*10)/10.
Why is that?
please try the below code
x[0].a.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
you can round off to 1 by changing regex patter from {0, 2} to {0, 1}
Thiss might work -- Math.floor() and toFixed(1) are the keys here... rounding will cause the original input to change to the nearest integer.
function roundToTenth(inputVal) {
return Math.floor(inputVal * 10) * 0.1;
}
console.log(roundToTenth(2.99).toFixed(1));
Division is slower than multiplication is generally - and definitely using Regular Expression Matching is going to be slower than multiplication is....
All I'm doing in the code above is saying "Take the number times 10 and then turn it into a straight Integer with no Decimals,
so
2.99 * 10 = 29.9 which then becomes 29
finally, since I use the operation * 0.1 it becomes a float like 2.900000004 and I use toFixed(1) to strip out all those pesky 0s at the end
I need to convert number starting with decimal like .15 to 0 rather then 0.15 in javascript.
using ParseInt(value) only work for leading zero numbers like 001 or 0.1.
can anyone provide me good solution ??
An input value is a String! Trying to use parseInt on a non-number (string decimal missing integer) will result in NaN when the parser tries to perform a string-to-number conversion:
parseInt(".15", 10) // NaN
In that case you need to first convert it to a Number:
parseInt(Number(".15"), 10) // 0
(or using the Unary +)
parseInt( +".15", 10) // 0
So I ran across a small piece of code that looks like this
Math.random() * 5 | 0 and was confused by what it did.
after some inspecting, it seems like the comparison turns the decimal into an integer. is that right? and so the piece of code is another way is saying give me a random number between 0 and 4. Can anyone explain why that is?
1) Math.random() function always return decimal value and will be less than one. Ex - 0.2131313
random()
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
2) Math.random()*5 will always be less than 5. (maxvalue - 4.99999).
3) The bitwise operator '|' will truncate the decimal values.
Edit : Paul is correct. '|' does more than just truncate.
But in this case Math.random()*5|0 - It truncates the decimal and returns the integar.