Javascript: Comparing two float values [duplicate] - javascript

This question already has answers here:
Javascript float comparison
(2 answers)
Closed 6 months ago.
I have this JavaScript function:
Contrl.prototype.EvaluateStatement = function(acVal, cfVal) {
var cv = parseFloat(cfVal).toFixed(2);
var av = parseFloat(acVal).toFixed(2);
if( av < cv) // do some thing
}
When i compare float numbers av=7.00 and cv=12.00 the result of 7.00<12.00 is false!
Any ideas why?

toFixed returns a string, and you are comparing the two resulting strings. Lexically, the 1 in 12 comes before the 7 so 12 < 7.
I guess you want to compare something like:
(Math.round(parseFloat(acVal)*100)/100)
which rounds to two decimals

Compare float numbers with precision:
var precision = 0.001;
if (Math.abs(n1 - n2) <= precision) {
// equal
}
else {
// not equal
}
UPD:
Or, if one of the numbers is precise, compare precision with the relative error
var absoluteError = (Math.abs(nApprox - nExact)),
relativeError = absoluteError / nExact;
return (relativeError <= precision);

The Math.fround() function returns the nearest 32-bit single precision float representation of a Number.
And therefore is one of the best choices to compare 2 floats.
if (Math.fround(1.5) < Math.fround(1.6)) {
console.log('yes')
} else {
console.log('no')
}
>>> yes
// More examples:
console.log(Math.fround(0.9) < Math.fround(1)); >>> true
console.log(Math.fround(1.5) < Math.fround(1.6)); >>> true
console.log(Math.fround(0.005) < Math.fround(0.00006)); >>> false
console.log(Math.fround(0.00000000009) < Math.fround(0.0000000000000009)); >>> false

Comparing floats using short notation, also accepts floats as strings and integers:
var floatOne = 2, floatTwo = '1.456';
Math.floor(floatOne*100) > Math.floor(floatTwo*100)
(!) Note: Comparison happens using integers. What actually happens behind the scenes: 200 > 145
Extend 100 with zero's for more decimal precision. For example use 1000 for 3 decimals precision.
Test:
var floatOne = 2, floatTwo = '1.456';
console.log(Math.floor(floatOne*100), '>', Math.floor(floatTwo*100), '=', Math.floor(floatOne*100) > Math.floor(floatTwo*100));

Comparing of float values is tricky due to long "post dot" tail of the float value stored in the memory. The simplest (and in fact the best) way is: to multiply values, for reducing known amount of post dot digits to zero, and then round the value (to rid of the tail).
Obviously both compared values must be multiplied by the same rate.
F.i.: 1,234 * 1000 gives 1234 - which can be compared very easily. 5,67 can be multiplied by 100, as for reducing the float comparing problem in general, but then it couldn't be compared to the first value (1,234 vel 1234). So in this example it need to be multiplied by 1000.
Then the comparition code could look like (in meta code):
var v1 = 1.234;
var v2 = 5.67;
if (Math.round(v1*1000) < Math.round(v2*1000)) ....

Related

Limit and round number [duplicate]

This question already has an answer here:
Limit the length of number by rounding it
(1 answer)
Closed 8 months ago.
I want to limit the number to max 5 digits by rounding the decimal. If we have less than 5 digits the number should stay untouched.
Could anyone help me to write that function?
function limitAndRoundNumber(number) {
...
}
Exemplary inputs and outputs:
limitAndRoundNumber(1.234) should return 1.234 (unchanged because number has less than 5 digits)
limitAndRoundNumber(1.234567) should return 1.2346
limitAndRoundNumber(12.34567) should return 12.346
limitAndRoundNumber(123.4567) should return 123.46
limitAndRoundNumber(1234.567) should return 1234.6
limitAndRoundNumber(12345) should return 12345
Input number can be grater than 0 and less than 100000
I tend to use the following to cut a number to a set number of decimals
Math.round(number * multiplier) / multiplier
Where 'multiplier' is 10 to the power of the number of decimals. Now you only need to figure out what the multiplier needs to be, and you can do that by rounding to a whole value and getting the string length of the number. So something like:
function limitAndRoundNumber(number) {
const wholeDigits = Math.round(number).toString().length;
const power = wholeDigits <= 5 ? 5 - wholeDigits : 0;
const multiplier = 10**power;
return Math.round(number * multiplier) / multiplier;
}
console.log(limitAndRoundNumber(1.23));
console.log(limitAndRoundNumber(1.234567));
console.log(limitAndRoundNumber(12.34567));
console.log(limitAndRoundNumber(123.4567));
console.log(limitAndRoundNumber(1234.567));
console.log(limitAndRoundNumber(12345));
console.log(limitAndRoundNumber(123456));
One solution is to convert the number to a string and use String.slice(0,requiredLength) to adjust the length before returning a number version of the string.
The length would depend on whether the number contained a decimal separator, which could be determined by a conditional within the function.
Working snippet:
function limitAndRoundNumber(number) {
const length = (number.toString().indexOf('.')) ? 6 : 5;
return parseFloat(number.toString().slice(0,length));
}
console.log(limitAndRoundNumber(1.234567));
console.log(limitAndRoundNumber(12.34567));
console.log(limitAndRoundNumber(123.4567));
console.log(limitAndRoundNumber(1234.567));
console.log(limitAndRoundNumber(12345));
console.log(limitAndRoundNumber(12));
console.log(limitAndRoundNumber(12.3));
The function could be modified to allow for any length, by including a length argument and referencing it in the ternary operator test for the decimal separator:
length = (number.toString().indexOf('.')) ? length+1 : length;

Negative Numbers Give Error NaN in Javascript [duplicate]

This question already has answers here:
Math.pow with negative numbers and non-integer powers
(2 answers)
Closed 3 years ago.
I am trying to write a code about changing numbers to its cube root but whenever i enter a negative number, i receive NaN error.
Tried to use string to number function called Number
let number = prompt("Enter a number");
if (number > 0 || number < 0){
let x = number**(1/3);
alert(x);
}
else if (number == 0){
alert(number);
}
else{
alert("Error");
}
I enter -8 for example, i expect it will give me -2 as result but i receive NaN
This is because cube-root of a negative number has complex numbers as solutions along with a negative real number, to get the negative real number you have to write a simple logic:
function cubeRoot(number){
const isNegative = number < 0;
const cubeRoot = Math.pow(Math.abs(number), 1/3);
return isNegative ? -cubeRoot : cubeRoot;
}
console.log(cubeRoot(-8));
console.log(cubeRoot(0));
console.log(cubeRoot(8));
There is a library available to do this: math.js
console.log(math.cbrt(-8));
console.log(math.cbrt(0));
console.log(math.cbrt(8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/6.2.1/math.js"></script>

Is it possible to generate an integer by using Math.random()*80 in JavaScript?

I know even if it can, the probability would be really small but is it theoretically possible?
According to the ECMAScript standard, there is only one number type: the double-precision 64-bit binary format IEEE 754 value (number between -(253 -1) and 253 -1). There is no specific type for integers.
So, are there any IEEE 754 numbers that become integer when multiplied by 80?
80 = 2*2*2*2*5. Since the value is stored using binary fractions, the numbers n/16, where n is in the range [1-15] can all be represented exactly. They also become an integer when multiplied by 80.
So there are at least 15 different values that will result in an integer when multiplied by 80.
Can the random number generator actually produce any of these values? I cannot say. That would depend on the javascript implementation.
... ? Yes :
You want an integer between 0 and 80 ?
var my_integer = parseInt (""+ 80 * Math.random());
EDIT You can also round it (floor,ceil) down & up:
Floor does, e.g. : 76,8=>76
var my_integer = Math.floor( parseInt (""+ 80 * Math.floor()));
Ceil does, e.g. : 76,8=>77
var my_integer = Math.ceil(parseInt (""+ 80 * Math.ceil()));
Yes it's possible. From node console:
> for(var i = 0; i < 1000000000; i++) {
... var rn = Math.random() * 80
... if(rn == Math.round(rn)) {
..... console.log('success')
..... break
..... }
... }
success
undefined
>

How can I check that a bit is set (without bitwise operation)?

Looking at the int 44 — I need Math.CEIL (log(2) 44) of binary places to represent 44.
(answer is 6 places)
6 places :
___ ___ ___ ___ ___ ___
32 16 8 4 2 1
But how can I check that (for example) the bit of 8 is checked or not ?
A simple solution will be do to :
((1<<3) & 44)>0 so this will check if the bit is set.
But please notice that behind the scenes the computer translates 44 to its binary representation and just check if bit is set via bitwise operation.
Another solution is just to build the binary myself via toString(2) or mod%2 in a loop
Question
Mathematically Via which formula, I can test if n'th bit is set ?
(I would prefer a non loop operation but pure single math phrase)
Divide by the value of the bit that you want to check
and test if the first bit is set (this can be tested with x mod 2 == 1)
Math expression:
floor(value/(2^bitPos)) mod 2 = 1
As JS function:
function isSet(value, bitPos) {
var result = Math.floor(value / Math.pow(2, bitPos)) % 2;
return result == 1;
}
Note: bitPos starts with 0 (bit representing the nr 1)
The 'bit' (actually any base) value of an indexed number index in a value val in base base can in general be calculated as
val = 1966;
index = 2;
base = 10;
alert (Math.floor(val/Math.pow(base,index)) % base);
result: 9
val = 44;
index = 3;
base = 2;
alert (Math.floor(val/Math.pow(base,index)) % base);
result: 1 (only 0 and 1 are possible here – the range will always be 0..base-1).
The combination of Math.floor (to coerce to an integer in Javascript) and Math.pow is kind of iffy here. Even in integer range, Math.pow may generate a floating point number slightly below the expected 'whole' number. Perhaps it is safer to always add a small constant:
alert (Math.floor(0.1+val/Math.pow(base,index)) % base);
You can simply check if the bit at the position is set to 1.
function isBitSet(no, index) {
var bin = no.toString(2);
// Convert to Binary
index = bin.length - index;
// Reverse the index, start from right to left
return bin[index] == 1;
}
isBitSet(44, 2); // Check if second bit is set from left
DEMO

javascript if number greater than number [duplicate]

This question already has answers here:
issue with comparing two numbers in javascript
(5 answers)
Closed 4 months ago.
I have this javascript function to validate if a number is greater than another number
function validateForm() {
var x = document.forms["frmOrder"]["txtTotal"].value;
var y = document.forms["frmOrder"]["totalpoints"].value;
if (x > y) {
alert("Sorry, you don't have enough points");
return false;
}
}
It's not working for some reason.
If I do alert(x) I get 1300, and alert(y) gives 999
This works....
function validateForm() {
var x = 1300;
var y = 999;
if (x > y) {
alert("Sorry, you don't have enough points");
return false;
}
}
You should convert them to number before compare.
Try:
if (+x > +y) {
//...
}
or
if (Number(x) > Number(y)) {
// ...
}
Note: parseFloat and pareseInt(for compare integer, and you need to specify the radix) will give you NaN for an empty string, compare with NaN will always be false, If you don't want to treat empty string be 0, then you could use them.
You're comparing strings. JavaScript compares the ASCII code for each character of the string.
To see why you get false, look at the charCodes:
"1300".charCodeAt(0);
49
"999".charCodeAt(0);
57
The comparison is false because, when comparing the strings, the character codes for 1 is not greater than that of 9.
The fix is to treat the strings as numbers. You can use a number of methods:
parseInt(string, radix)
parseInt("1300", 10);
> 1300 - notice the lack of quotes
+"1300"
> 1300
Number("1300")
> 1300
You can "cast" to number using the Number constructor..
var number = new Number("8"); // 8 number
You can also call parseInt builtin function:
var number = parseInt("153"); // 153 number
Do this.
var x=parseInt(document.forms["frmOrder"]["txtTotal"].value);
var y=parseInt(document.forms["frmOrder"]["totalpoints"].value);

Categories

Resources