Why does Firebug say toFixed() is not a function? - javascript

I am using jQuery 1.7.2 and jQuery UI 1.9.1. I am using the code below within a slider. (http://jqueryui.com/slider/)
I have a function that should test two values and depending on the difference between the two values reformat them (to the appropriate decimal place). If the difference is greater than 10, I will parse out the integer. If the difference is greater than 5, it should keep one decimal. Everything else, I will keep two decimals.
When I enter two values that have a difference that is ten or less, I use the toFixed() function. And, in Firebug, I see an error:
TypeError: Low.toFixed is not a function
Low = Low.toFixed(2);
Is there something simple that I am doing wrong?
Here is my code:
var Low = $SliderValFrom.val(),
High = $SliderValTo.val();
// THE NUMBER IS VALID
if (isNaN(Low) == false && isNaN(High) == false) {
Diff = High - Low;
if (Diff > 10) {
Low = parseInt(Low);
High = parseInt(High);
} else if (Diff > 5) {
Low = Low.toFixed(1);
High = High.toFixed(1);
} else {
Low = Low.toFixed(2);
High = High.toFixed(2);
}
}

toFixed isn't a method of non-numeric variable types. In other words, Low and High can't be fixed because when you get the value of something in Javascript, it automatically is set to a string type. Using parseFloat() (or parseInt() with a radix, if it's an integer) will allow you to convert different variable types to numbers which will enable the toFixed() function to work.
var Low = parseFloat($SliderValFrom.val()),
High = parseFloat($SliderValTo.val());

That is because Low is a string.
.toFixed() only works with a number.
Try doing:
Low = parseFloat(Low).toFixed(..);

Low is a string.
.toFixed() only works with a number.
A simple way to overcome such problem is to use type coercion:
Low = (Low*1).toFixed(..);
The multiplication by 1 forces to code to convert the string to number and doesn't change the value.

You need convert to number type:
(+Low).toFixed(2)

parseFloat() will return NaN for empty string, why not using Number() function instead?
Values of other types can be converted to numbers using the Number() function.
parseFloat('').toFixed(2) // "NaN"
Number('').toFixed(2) // "0.00"
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number

Low = Number(Low).toFixed(1);
add the Number function to convert Low into a number.

In a function, use as
render: function (args) {
if (args.value != 0)
return (parseFloat(args.value).toFixed(2));
},

Related

Why I can't convert string to number without losing precision in JS?

We all know that +, Number() and parseInt() can convert string to integer.
But in my case I have very weird result.
I need to convert string '6145390195186705543' to number.
let str = '6145390195186705543';
let number = +str; // 6145390195186705000, but should be: 6145390195186705543
Could someone explain why and how to solve it?
Your number is above the Number.MAX_SAFE_INTEGER (9,007,199,254,740,991), meaning js might have a problem to represent it well.
More information
You are outside the maximum range. Check in your console by typing Number.MAX_SAFE_INTEGER
If you want a number outside this range, take a look into BigInt that allows to define numbers beyond the safe range
https://developers.google.com/web/updates/2018/05/bigint
Read the documentation well before using it since the usage is different than usual
I am guessing this is to solve the plusOne problem in leetcode. As others have answered, you cannot store value higher than the max safe integer. However you can write logic to add values manually.
If you want to add one to the number represented in the array, you can use the below function. If you need to add a different value, you need to tweak the solution a bit.
var plusOne = function(digits) {
let n = digits.length, carry=0;
if(digits[n-1]<9){
digits[n-1] +=1;
} else{
digits[n-1] = 0;
carry=1;
for(let i=n-2;i>=0;i--){
if(digits[i]<9){
digits[i]+=1;
carry=0;
break;
}else{
digits[i]=0;
}
}
if(carry>0){
digits.unshift(carry);
}
}
return digits;
};
Short answer: Your string represents a number to large to fit into the JavaScript number container.
According to the javascript documentation the maximum safe number is 2^53 which is 9007199254740992 source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
When you try and convert your number you're creating an overflow exception so you get weird results.

Javascript: "+" sign concatenates instead of giving sum of variables

I am currently creating a site that will help me quickly answer physics questions.
As it happens, the code didn't run as expected, here is the code
if (option == "dv") {
var Vinitial = prompt("What is the Velocity Initial?")
var acceleration = prompt("what is the acceleration?")
var time = prompt("what is the time?")
Vfinal = Vinitial + acceleration * time
displayV.innerHTML = "v= vf= " + Vfinal + "ms" + sup1.sup();
}
Now, let's say Vinitial was 9, acceleration was 2, and time was 3.
When the code runs, instead of getting 15 for "Vfinal", I get 96.
I figured out that it multiplies acceleration and time fine, and then just concatenates the 9 at the beginning, with 6 (the product of 2 * 3).
I have fixed it for now by using
Vfinal = acceleration * time - (-Vinitial)
which avoids using the "+" sign, but I don't want to have to keep doing this. How do I fix it?
you are dealing with strings here, and math operations on strings will mess up. Remember when ever you are doing math operations you have to convert the data into actual numbers and then perform the math.
Use parseInt() more Details here
Your code should change to
Vfinal = parseInt(Vinitial,10) + parseInt(acceleration,10) * parseInt(time,10);
Edit 1: If the numbers are decimal values then use parseFloat() instead
So the code would be
Vfinal = parseFloat(Vinitial) + parseFloat(acceleration) * parseFloat(time);
Object-Oriented JavaScript - Second Edition: As you already know, when you use the plus sign with two numbers, this
is the arithmetic addition operation. However, if you use the plus
sign with strings, this is a string concatenation operation, and it
returns the two strings glued together:
var s1 = "web";
var s2 = "site";
s1 + s2; // website
The dual purpose of the + operator is a source of errors. Therefore,
if you intend to concatenate strings, it's always best to make sure
that all of the operands are strings. The same applies for addition;
if you intend to add numbers, make sure the operands are numbers.
You can use "+" operator with prompt() to convert returned values from string to int
var Vinitial = +prompt("What is the Velocity Initial?");
var acceleration = +prompt("what is the acceleration?");
var time = +prompt("what is the time?");
Explanation:
var a = prompt('Enter a digit');
typeof a; // "string"
typeof +a; // "number"
If you will enter non-digit data +a gives you NaN. typeof NaN is "number" too :)
You will get the same result with parseInt():
var Vinitial = parseInt(prompt("What is the Velocity Initial?"), 10);
var acceleration = parseInt(prompt("what is the acceleration?"), 10);
var time = parseInt(prompt("what is the time?"), 10);
developer.mozilla.org: parseInt(string, radix);
string: The value to parse.
radix: An integer between 2 and 36 that represents the radix (the base in mathematical numeral systems) of the above mentioned string.
Specify 10 for the decimal numeral system commonly used by humans.
Always specify this parameter to eliminate reader confusion and to
guarantee predictable behavior. Different implementations produce
different results when a radix is not specified, usually defaulting
the value to 10.
Epilogue:
Object-Oriented JavaScript - Second Edition: The safest thing to do is to always specify the radix. If you omit the radix, your code
will probably still work in 99 percent of cases (because most often
you parse decimals), but every once in a while it might cause you a
bit of hair loss while debugging some edge cases. For example, imagine
you have a form field that accepts calendar days or months and the
user types 06 or 08.
Epilogue II:
ECMAScript 5 removes the octal literal values and avoids the confusion
with parseInt() and unspecified radix.
The Problem is, Your value has been took it in a form of string .. so convert your value into Int using parseInt(accelaration).. then it will work ..
Vfinal = parseInt(Vinitial) + parseInt(acceleration) * parseInt(time)
//use ParseInt
var a=10,b=10;
var sum=parseInt(a+b);
ex:
parseInt(Vinitial + acceleration) * time

Is there a way to distinguish integers from very near decimals in Javascript?

Look at those evaluations (actual dump from node 0.10.33)
> parseFloat(2.1e-17) === parseInt(2.1e-17)
false
> parseFloat(2.1e-17 + 2) === parseInt(2.1e-17 + 2)
true
> parseFloat(2.000000000000000000000000000000000009) === parseInt(2.00000000000000000000000000000000000009)
true
How can I tell integers from decimals very near to integers?
It seems that JS (or at least V8) doesn't care about digits smaller than 10^-16 when doing calculations, even if the 64bit representation used by the language (reference) should handle it.
Your examples are pretty much straight forward to explain. First thing to note is, that parseInt() and parseFloat() take a string as an input. So you inputs first get converted to string, before actually getting parsed.
The first is easy to see:
> parseFloat(2.1e-17) === parseInt(2.1e-17)
false
// look at the result of each side
parseFloat(2.1e-17) == 2.1e-17
parseInt(2.1e-17) == 2
When parsing the string "2.1e-17" as integer, the parse will stop at the dot as that is no valid digit and return everything it found until then, which is just 2.
> parseFloat(2.1e-17 + 2) === parseInt(2.1e-17 + 2)
true
// look at the result of each side
parseFloat(2.1e-17 + 2) == 2
parseInt(2.1e-17 + 2) == 2
Here the formula in the parameter will be evaluated first. Due to the limitations of floating point math (we just have 52bit for the mantissa and can't represent something like 2.000000000000000021), this will result in just 2. So both parseX() function get the same integer parameter, which will result in the same parsed number.
> parseFloat(2.000000000000000000000000000000000009) === parseInt(2.00000000000000000000000000000000000009)
true
Same argument as for the second case. The only difference is, that instead of a formula, that gets evaluated, this time it is the JavaScript parser, which converts your numbers just to 2.
So to sum up: From JavaScript's point of view, your numbers are just the same. If you need more precision, you will have to use some library for arbitrary precision.
This is something I learned from ReSharper
instead of using expressions like
if (2.00001 == 2) {}
try
if (Math.abs(2.00001 - 2) < tolerance) {}
where tolerance should be an aceptable value for you for example .001
so all values wich difference is less than .001 will be equals
Do you really need 10^-16 precision I mean that is why 1000 meter = 1 kilometer, just change the unit of the output so you dont have to work with all those decimals

Decimal Value addition not working, returning string

I want to do some math like plus, minus etc. with decimal values.
So i wrote two functions;
function to_decimal(i){
var $dec = parseFloat(i);
return $dec.toFixed(2);
}
function calc_price(){
var $t = $('#sub_total .total').text();
var $total = to_decimal($t);
$('#price_list ul li').each(function(){
var $p = to_decimal($(this).find('.item_price').text());
$total = $total + $p;
});
$t = $('#sub_total .total').text($total);
}
But these functions not working correctly i think because the result is returning string like 0.0010.30
Where is the problem?
You need to add a + infront of that statement and you're fine:
return +$dec.toFixed(2);
That will convert the string into a number. If the string cannot get converted, it'll return the NaN value.
Instead of:
return $dec.toFixed(2);
Do:
return Math.round($dec*100)/100;
The toFixed method returns a string. Any mathematical operation that doesn't affect the output can be used to convert the string to a number (except addition, whose operator unfortunately doubles as the string concatenation operator):
$dec.toFixed(2) - 0
$dec.toFixed(2) / 1
$dec.toFixed(2) * 1
+$dec.toFixed(2)
These are the fastest methods. However, if speed is not a concern (and it probably isn't when performing a small number of operations) then the clearest, most-readable method to convert a string to a number is the Number constructor:
Number($dec.toFixed(2))
Edit: The performance information above may no longer be universally true. The Number constructor is indeed considerably slower than each of the alternatives in IE 7.0 and Firefox 5, but actually performs the best in Chrome 12.0.742.
See:
http://jsperf.com/js-string-to-number-conversion

Convert an entire String into an Integer in JavaScript

I recently ran into a piece of code very much like this one:
var nHours = parseInt(txtHours);
if( isNaN(nHours)) // Do something
else // Do something else with the value
The developer who wrote this code was under the impression that nHours would either be an integer that exactly matched txtHours or NaN. There are several things wrong with this assumption.
First, the developer left of the radix argument which means input of "09" would result in a value of 0 instead of 9. This issue can be resolved by adding the radix in like so:
var nHours = parseInt(txtHours,10);
if( isNaN(nHours)) // Do something
else // Do something else with the value
Next, input of "1.5" will result in a value of 1 instead of NaN which is not what the developer expected since 1.5 is not an integer. Likewise a value of "1a" will result in a value of 1 instead of NaN.
All of these issues are somewhat understandable since this is one of the most common examples of how to convert a string to an integer and most places don't discuss these cases.
At any rate it got me thinking that I'm not aware of any built in way to get an integer like this. There is Number(txtHours) (or +txtHours) which comes closer but accepts non-integer numbers and will treat null and "" as 0 instead of NaN.
To help the developer out I provided the following function:
function ConvertToInteger(text)
{
var number = Math.floor(+text);
return text && number == text ? number : NaN;
}
This seems to cover all the above issues. Does anyone know of anything wrong with this technique or maybe a simpler way to get the same results?
Here, that's what I came up with:
function integer(x) {
if (typeof x !== "number" && typeof x !== "string" || x === "") {
return NaN;
} else {
x = Number(x);
return x === Math.floor(x) ? x : NaN;
}
}
(Note: I updated this function to saveguard against white-space strings. See below.)
The idea is to only accept arguments which type is either Number or String (but not the empty string value). Then a conversion to Number is done (in case it was a string), and finally its value is compared to the floor() value to determine if the number is a integer or not.
integer(); // NaN
integer(""); // NaN
integer(null); // NaN
integer(true); // NaN
integer(false); // NaN
integer("1a"); // NaN
integer("1.3"); // NaN
integer(1.3); // NaN
integer(7); // 7
However, the NaN value is "misused" here, since floats and strings representing floats result in NaN, and that is technically not true.
Also, note that because of the way strings are converted into numbers, the string argument may have trailing or leading white-space, or leading zeroes:
integer(" 3 "); // 3
integer("0003"); // 3
Another approach...
You can use a regular expression if the input value is a string.
This regexp: /^\s*(\+|-)?\d+\s*$/ will match strings that represent integers.
UPDATED FUNCTION!
function integer(x) {
if ( typeof x === "string" && /^\s*(\+|-)?\d+\s*$/.test(x) ) {
x = Number(x);
}
if ( typeof x === "number" ) {
return x === Math.floor(x) ? x : NaN;
}
return NaN;
}
This version of integer() is more strict as it allows only strings that follow a certain pattern (which is tested with a regexp). It produces the same results as the other integer() function, except that it additionally disregards all white-space strings (as pointed out by #CMS).
Updated again!
I noticed #Zecc's answer and simplified the code a bit... I guess this works, too:
function integer(x) {
if( /^\s*(\+|-)?\d+\s*$/.test(String(x)) ){
return parseInt(x, 10);
}
return Number.NaN;
}
It probaly isn't the fastest solution (in terms of performance), but I like its simplicity :)
Here's my attempt:
function integer(x) {
var n = parseFloat(x); // No need to check typeof x; parseFloat does it for us
if(!isNaN(n) && /^\s*(\+|-)?\d+\s*$/.test(String(x))){
return n;
}
return Number.NaN;
}
I have to credit Šime Vidas for the regex, though I would get there myself.
Edit: I wasn't aware there was a NaN global. I've always used Number.NaN.
Live and learn.
My Solution involves some cheap trick. It based on the fact that bit operators in Javascript convert their operands to integers.
I wasn't quite sure if strings representing integers should work so here are two different solutions.
function integer (number) {
return ~~number == number ? ~~number : NaN;
}
function integer (number) {
return ~~number === number ? ~~number : NaN;
}
The first one will work with both integers as strings, the second one won't.
The bitwise not (~) operator will convert its operand to an integer.
This method fails for integers bigger which can't be represented by the 32bit wide representation of integers (-2147483647 .. 2147483647).
You can first convert a String to an Integer, and then back to a String again. Then check if first and second strings match.
Edit: an example of what I meant:
function cs (stringInt) {
var trimmed = stringInt.trim(); // trim original string
var num = parseInt(trimmed, 10); // convert string to integer
newString = num + ""; // convert newly created integer back to string
console.log(newString); // (works in at least Firefox and Chrome) check what's new string like
return (newString == trimmed); // if they are identical, you can be sure that original string is an integer
}
This function will return true if a string you put in is really an integer. It can be modified if you don't want trimming. Using leading zeroes will fail, but, once again, you can get rid of them in this function if you want. This way, you don't need to mess around with NaN or regex, you can easily check validity of your stringified integer.

Categories

Resources