Negative Numbers Give Error NaN in Javascript [duplicate] - javascript

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>

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;

how can round the number in specific format? [duplicate]

This question already has answers here:
Javascript roundoff number to nearest 0.5
(10 answers)
Closed 6 years ago.
I want to round the number in specific format in jquery
For ex.
var First = 3.52
if last value after decimal point 2 is less then 3 then it should be round to 0
if last value after decimal point 2 is beetween then 3 to 7 then it should be round to 5
if last value after decimal point 2 is more then 7 then it should be round to 10
Like
if(var First = 1.21) { var Answer = 1.20 }
if(var First = 1.24) { var Answer = 1.25 }
if(var First = 1.28) { var Answer = 1.30 }
i have tried Round and Ceil , Floor but doesnt work for me
To achieve this you can use Math.round() to the nearest 0.05, like this:
Math.round(number * 20) / 20;
To make it easier you can extract this to a function:
console.log(round(1.21)); // = 1.20
console.log(round(1.24)); // = 1.25
console.log(round(1.28)); // = 1.30
function round(num) {
return (Math.round(num * 20) / 20).toFixed(2);
}
Note the use of toFixed(2) to force the result to 2 decimal places. Beware that this method returns a string, so if you are planning on doing any calculations with the value you will need to run the result through parseFloat().

JavaScript Detecting Octal Value at Different Scenario

var x = 02345;
var y = x.toString();
alert(y);
I realized that there is a problem converting leading zeroes number to string in JavaScript using the toString() method.
As you can see from the output of the code above, the output is 1253 instead of the supposedly 02345.
If the leading zero is removed, the code will work as expected, why? What is happening with the code above so I can change it to work as expected.
var x = 2345;
var y = x.toString();
alert(y);
EDIT : The reason I asked this question is because I have two different codes that work differently despite being very similar. After reading that this question has nothing to do with the toString() method, why does the first set of code below not detect the number as an octal value but the second set of code does.
var num=window.prompt(); // num = 0012222
var str = num.toString();
var result = [str[0]];
for(var x=1; x<str.length; x++)
{
if((str[x-1]%2 === 0)&&(str[x]%2 === 0))
{
result.push('-', str[x]);
}
else
{
result.push(str[x]);
}
}
alert(result.join('')); //Outputs : 0-012-2-2-2
The other code :
function numberDash(num) {
var stringNumber = num.toString();
var output = [stringNumber[0]];
for (var i = 1; i < stringNumber.length; i++) {
if (stringNumber[i-1] % 2 === 0 && stringNumber[i] % 2 === 0) {
output.push('-', stringNumber[i]);
} else {
output.push(stringNumber[i]);
}
}
return output.join('');
}
numberDash(0012222) // Outputs : "52-6-6";
Many JavaScript engines add octal numeric literals to the specification. The leading zero indicates octal (base 8). 2345 in base 8 (octal) is 1253 in base 10 (decimal):
Octal Decimal
----- --------------------
2 2 * 8 * 8 * 8 = 1024
3 3 * 8 * 8 = 192
4 4 * 8 = 32
5 5
----- --------------------
2345 1253
You can disable that using strict mode. See §B.1.1 of the specification. Doing so makes 02345 a syntax error.
So it's nothing to do with toString, it's just that the 02345 in your code isn't the value you expect.
Re your updated question:
why does the first set of code below not detect the number as an octal value but the second set of code does
Because in the first code, you're not dealing with a number, you're dealing with a string. window.prompt returns a string, not a number, even if what you type in is all digits.
Even if you converted the string to a number via Number(num) or +num, the rules for runtime string->number conversion are different from the rules for parsing JavaScript source code.
var x = 02345;
var y = x.toString("8");
alert(y);
This will give you 2345
Leading zero is interpreted as octal value.
If you need number converted to string with leading zero, use my method but simply modify it like this var y = "0" + x.toString("8")

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);

Javascript: Comparing two float values [duplicate]

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)) ....

Categories

Resources