Save integer as float - javascript

function prec(numb){
var numb_string = numb.toString().split('.')
return numb_string[(numb_string.length - 1)].length
}
function randy(minimum, maximum) {
var most_accurate = Math.max ( prec(minimum), prec(maximum) );
return ( ( Math.random() * ( maximum - minimum ) + minimum ).toFixed( most_accurate ) );
}
// returns random numbers between these points. 1 decimal place of precision:
console.log( randy(2.4,4.4) );
// returns random numbers between these points. 3 decimal places of precision:
console.log( randy(2.443,4.445) );
// returns random numbers between these points. Want 3 decimal places of precision. However, get 0:
console.log( randy(2.000,4.000) );
// Why do I get 0 decimal places? Because floats are rounded into integers automatically:
console.log( 4.0 ); // want 4.0 to be logged. Instead I get '4'
You don't need to read how the functions work. Just the console logs.
Basically, I need to return a random number between two points to a degree of precision. The precision is automatically derived from the most precise float passed to the randy function.
This works fine when the number range is 3.5 3.7 or 34.4322 800.3233 but not 2.0, 3.0 or 4.0000, 5.0000
Then the number is appears to be automatically saved as an integer:
console.log( 2.0 ) //=> 2
I want to extend the Number prototype so that 2.0 is saved as 2.0 so that this function can find the precision:
function prec(numb){
var numb_string = numb.toString().split('.')
return numb_string[(numb_string.length - 1)].length
}
It currently thinks that 3.000000000 has a precision of 0 decimal places because if 3E8 is passed in as the numb parameter, it's read as 3. I want it read as 3.000000000
While I can do this randy(2.toFixed(3),3.toFixed(3)) it gets unreadable and it would be undeniably nicer to do this for smaller precisions: randy(2.000,3.000).
Is this possible?
Fiddle

There is a clever way to solve this problem , is to define a class that helps you managing the number values and the decimal values.
function HappyNumber()
{
this.value = (typeof(arguments[0]) == "number") ? arguments[0] : 0;
this.decimal = (typeof(arguments[1]) == "number") ? arguments[1] : 0;
this.Val = function()
{
return parseFloat(this.value.toFixed(this.decimal));
}
this.toString = function()
{
return (this.value.toFixed(this.decimal)).toString();
}
}
How this class works
Now first thing to do is to create a new number like this
var Num = HappyNumber(4.123545,3);
// first argument is the value
// and second one is decimal
To get the value of your variable, you should use the function Val like this
console.log(Num.Val()); // this one prints 4.123 on your console
The most important part is this one, when you use the toString function it return your number
Num.toString() // it returns "4.123"
(new HappyNumber(4,4)).toString(); // it returns "4.0000"
Now you pass arguments as (HappyNumber), and inside your function use toString and it returns the right value you need and it works with numbers like 1.00 2.000 4.00000

This will do what you want. (Warning: This is probably not a good idea.)
Number.prototype.toString = function () { return this.toFixed(1); }

Related

Limit decimal places to specific situations (not round)

Im looking to limit a number do 2 decimal places, but only when the rest is zero. I dont want to round the numbers.
I tried using this example
(1.0000).toFixed(2)
the result would be 1.00, but if i have a number like (1.0030).toFixed(2), the result should be 1.003.
I tried using parseFloat with a combination of toFixed but doesn´t get the result i want.
Is there any function in javascript that does what im trying to achieve.
So you want a minimum of two decimals? Here's one way:
function toMinTwoDecimals(numString) {
var num = parseFloat(numString);
return num == num.toFixed(2) ? num.toFixed(2) : num.toString();
}
Examples:
toMinTwoDecimals("1.0030"); // returns "1.003"
toMinTwoDecimals("1.0000"); // returns "1.00"
toMinTwoDecimals("1"); // returns "1.00"
toMinTwoDecimals("-5.24342234"); // returns "-5.24342234"
In case you want to leave numbers with less than two decimals untouched, use this instead:
function toMinTwoDecimals(numString) {
var num = parseFloat(numString);
// Trim extra zeros for numbers with three or more
// significant decimals (e.g. "1.0030" => "1.003")
if (num != num.toFixed(2)) {
return num.toString();
}
// Leave numbers with zero or one decimal untouched
// (e.g. "5", "1.3")
if (numString === num.toFixed(0) || numString === num.toFixed(1)) {
return numString;
}
// Limit to two decimals for numbers with extra zeros
// (e.g. "1.0000" => "1.00", "1.1000000" => "1.10")
return num.toFixed(2);
}

Adding Two Decimal Places using JavaScript

Good day Everyone!
I want to know how to return the output with two decimal places. Instead of 10,000 I want it to return 10,000.00. Also I already put .toFixed(2) but it's not working.
When the amount has decimal number other than zero, the values appear on the printout, but when the decimal number has a zero value, the Zeros won't appear on the printout.
Also, I have added a value of Wtax that was pulled-out on a "Bill Credit" Transaction.
Output:
Numeral.js - is a library that you can use for number formatting.
With that you can format your number as follows:
numeral(10000).format('$0,0.00');
Hope this will help you.
You can try this
var x = 1000; // Raw input
x.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') //returns you 1,000.00
Alternately you can use Netsuite's currency function too
nlapiFormatCurrency('1000'); // returns you 1,000.00
nlapiFormatCurrency('1000.98'); // returns you 1,000.98
You might consider below code. It can round off decimal values based on the decimal places.
This also addresses the issue when rounding off negative values by getting first the absolute value before rounding it off. Without doing that, you will have the following results which the 2nd sample is incorrect.
function roundDecimal(decimalNumber, decimalPlace)
{
//this is to make sure the rounding off is correct even if the decimal is equal to -0.995
var bIsNegative = false;
if (decimalNumber < 0)
{
decimalNumber = Math.abs(decimalNumber);
bIsNegative = true;
}
var fReturn = 0.00;
(decimalPlace == null || decimalPlace == '') ? 0 : decimalPlace;
var multiplierDivisor = Math.pow(10, decimalPlace);
fReturn = Math.round((parseFloat(decimalNumber) * multiplierDivisor).toFixed(decimalPlace)) / multiplierDivisor;
fReturn = (bIsNegative) ? (fReturn * -1) : fReturn;
fReturn = fReturn.toFixed(decimalPlace)
return fReturn;
}
Below are the test sample
And this test sample after addressing the issue for negative values.

Decimal Comparison without rounding in javascript

I have 2 textboxex for decimal values and I need to compare them in JavaScript. The scenario is
var first = $('#txtFirst').val();
var second= $('#txtSecond').val();
In textboxex I'm entering following values
first => 99999999999998.999999997
second => 99999999999998.999999991
I tried the below code
if (parseFloat(parseFloat(first).toFixed(10)) <= parseFloat(parseFloat(second).toFixed(10)))
This returns true because it rounds it so both the values becomes 99999999999999. How to fix it?
Just compare without converting into integer
var first = $('#txtFirst').val();
var second= $('#txtSecond').val();
if ( first == second )
{
// they are equal
}
if you want to compare upto 10 decimals then
var first10Decimals = first.split(".").pop().substring(0,10);
var second10Decimals = second.split(".").pop().substring(0,10);
if ( first10Decimals == second10Decimals )
{
//they are equal
}
Vanilla JavaScript can't handle such big numbers. You should use something like big.js that is designed to work with arbitrary large numbers :
GitHub : https://github.com/MikeMcl/big.js/
Documentation : https://mikemcl.github.io/big.js/

Testing for Rounding Errors in JavaScript

How can I determine if a number is too big (will cause rounding errors if math is performed) in JavaScript.
For example, I have a function that formats percentages. If it cannot format the passed in value correctly, I want it to return the value exactly as it was passed in.
function formatPercent(x, decimals) {
var n = parseFloat(x); // Parse (string or number)
if ($.isNumeric(n) === false) {
return x; // Return original if not a number
} else {
return n.toFixed(decimals) + '%'; // Return formatted string
}
};
alert(formatPercent(276403573577891842, 2)); // returns 276403573577891840.00%
Since formatting such a huge number is a corner case and not expected, I'd prefer to just return the number as it was passed in. What is the limit before the rounding errors start and how would I check for them?
Update:
What is JavaScript's highest integer value that a Number can go to without losing precision? says precision works up to +/- 9007199254740992. I am testing to see if that is all I need to check against to safely fail and return the passed in value unmodified.
If you always pass x in as a string, that will ensure that there are no rounding errors. The problem is that 276403573577891842 is being rounded right as the number literal is parsed, but if you use strings, that will never happen. Try doing this:
function formatPercent(x, decimals) {
if(typeof x != "string" && typeof x != "number") return x;
x = x+"";//convert to string if it is a number
var r = /^(?:(\d+)(\.\d*)?|(\d*)(\.\d+))$/;// RegExp for matching numerical strings
return x.replace(r, function(match, int, dec){
if(decimals>0){
int = (typeof int == "string"?int:"");//if passed string didn't have integers
dec = (typeof dec == "string"?dec:".");//if passed string didn't have decimals
while(dec.length-1<decimals) dec += "0";//pad zeroes until dec.length-1==decimals
return int+dec.slice(0,decimals+1)+"%";//in case dec.length-1>decimals
}
int = (typeof int == "string"?int:"0");//if passed string didn't have integers
return int+"%";
});
// Return formatted string or original string conversion if no match found
}
alert(formatPercent("276403573577891842", 1));// returns 276403573577891842.0%
alert(formatPercent("276403573577891842.55", 1));// returns 276403573577891842.5%
alert(formatPercent("276403573577891842.55", 0));// returns 276403573577891842%
alert(formatPercent(".55", 1));//returns .5%
alert(formatPercent(".55", 0));//returns 0%
alert(formatPercent(276403573577891842, 1));// returns 276403573577891840.0%
alert(formatPercent("this is not a number", 2));// returns this is not a number
alert(formatPercent({key:"not number or string"}, 2));// returns the object as it was
Even though formatPercent still fails in the case of passing a number, this will prevent rounding error from passed strings. Please note this is not incorrect, as the only case in which it will fail is when a number that is too large is hard-coded as a parameter.
function formatPercent(x, decimals) {
var n = parseFloat(x); // Parse (string or number)
if ($.isNumeric(n) === false) {
return x; // Return original if not a number
} else {
var d = Math.pow(10, decimals)
return (Math.round(n * d) / d).toString() + "%";
}
};
Using rounding will drop the decimal if it's .00
This is what I used to catch too big or too small integers:
function getSafeNumber(x) {
var n = parseFloat(x); // Parse and return a floating point number
if ($.isNumeric(n) === false ||
n >= 9007199254740992 ||
n <= -9007199254740992) {
return false; // Not numeric or too big or too small
} else {
return n; // return as number
}
};
No greater than nine quardbillion will cause this type of error due to internal representation of no

looking for alternative way to do isNaN test

I'm looking for an alternative way to do an isNaN test
My original code looked like this. The code works, but I noticed that num1 changes type, which is ugly
// example 1: num1 changes type
num1 = parseInt(str1, 10);
if isNaN(num1){num1=-1;}
I changed it to this, but this one uses duplicate code
// example 2: duplicate code
if (isNaN(parseInt(str1,10))){num1=-1;}
else {num1=parseInt(str1,10);}
At first I was thinking about adding an extra variable to store parseInt(str1,10) but that variable will change type, too and is therefore in effect the same as example 1.
Is there an alternative to example 1 or 2?
by changes type I mean this
console.log(typeof(isNaN("123"))); // boolean
console.log(typeof(isNaN("abc"))); // boolean
console.log(typeof(parseInt("123", 10))); // number
console.log(typeof(parseInt("abc", 10))); // number
.
console.log(typeof(Number("123"))); // number
console.log(typeof(Number("abc"))); // number
console.log(Number("123")); // 123
console.log(Number("abc")); // NaN
First, I would suggest that parseInt() isn't the best choice. For example:
var x = parseInt("123hello world how are you today?", 10);
will set "x" to 123 and simply ignore the trailing garbage.
You could set up a functional way to do this, if you really wanted to avoid the intermediate temporary value:
function ifNumeric( s, f ) {
s = +s;
if (!isNaN(s)) f(s);
}
ifNumeric( someString, function( n ) { /* whatever, with "n" being a number */ } );
but that seems a little extreme. But anyway note that in that example the + operator is used to coerce the value of the variable to the "number" type. You could alternatively use the "Number" constructor, but not as a constructor:
var numeric = Number( someString );
Either of those will give you a NaN if the string isn't a completely valid number without trailing garbage.
edit — if you just want a safe "give me a number" converter:
function toNumber( value, ifGarbage ) {
value = +value;
return isNaN(value) ? ifGarbage : value;
}
var num1 = toNumber( str1, -1 );

Categories

Resources