(newbie here)
i have large floating-point arrays created by node.js that i need to pass to s client-side jquery-ajax function. the goal is download it the fastest way possible.
we can safely round off the floating-point to the hundredth position, maybe even the tenth position - but i still need to experiment to see which one works best.
so far i have multiplied each array value by 100 and rounded off to just have three digits:
wholeNbrValue = Math.round(floatingPointValue * Math.pow(10, 3));
so for example 0.123456 would become 123. then each set of digits is appended to a string:
returnString += sprintfJs('%03d', wholeNbrValue) ;
i end up with a rather long ascii string of digits. then i might use something like fs.createWriteStream to store the string on the server as an ordinary file, and later use jquery-ajax to fetch it on the client side.
my question: what might be the optimum way to store a numeric only string? i am tempted to loop back through the string again and use something like charCodeAt() and just grab up every two positions as an ascii value, or even grab every 64 digits and convert it to a four-byte hex value.
or perhaps is there some way using node to actually store a binary floating-point array and later retrieve it with jquery-ajax?
thank you very much.
Related
I'm looking to add decimals to the end of my integer. As an example:
15 => 15.00
The problem with methods like toFixed is that it will convert it into a string. I've tried to use parseFloat() and Number() on the string, but it'll convert it back to an integer with no decimals.
Is this possible? If not, can someone explain to me the logic behind why this isn't possible?
EDIT: Welp the intent was to display the number as a number, but from the going consensus, it looks like the way the only way to go about it is to use a string. Found an answer on the why: https://stackoverflow.com/a/17811916/8869701
The problem you are finding is that all numbers in javascript are floats.
a = 0.1
typeof a # "number"
b = 1
typeof b # number
They are the same.
So there is no real way to convert to from an integer to a float.
This is the reason that all of the parseFloat etc are string methods for reading and writing numbers from strings. Even if you did have floats and integers, specifying the precision of a number only really makes sense when you are displaying it to a user, and for this purpose it will be converted to a string anyway.
Depending on your exact use case you will need to use strings if you want to display with a defined precision.
When working with numbers 15 and 15.00 are equal. It wouldn't make any sense to use memory to store those trailing or leading zeros.
If that information is needed it is usually for displaying purposes. In that case a string is the right choice.
In case you need that value again you can parse the string as a number.
I am having a little problem with rounding numbers which are brought in from html.
For example a value extracted from <input id="salesValue"> using var salesValue = $("salesValue").val() would give me a text value.
So if I did something like var doubleSalesValue = salesValue + salesValue; , it would return the number as a concatenation instead of summation of the two values.
I could use var doubleSalesValue = salesValue * 2.0; which does return the value which is to multiple decimal places. However, if I did want to use the other method, how can I approach the situation.
What methods do you use? I have created a function which I run on each number where I want to restrict the decimal places along with converting the type to number
function round(number, figure){
return Number(Number(number).toFixed(figure));
}
I have to run Number initially to make sure that the value is converted to type number and has the method toFixed, otherwise it would throw an error here. Then I have to round the number again to the number of decimal places as required by the function, and somehow after running the toFixed method the number would sometimes turn to a string.
So, I decided to run the Number function Number(number).toFixed(figure)
Is there anything else or any different paradigm that you follow?
EDIT: I want to know if what I am doing here is conventional or are there better methods for this in general?
If you want to round it to 2 decimals you can simply do this:
var roundedNum = Math.round(parseFloat(originalNum) * 100) / 100;
Regarding your question:
and somehow after running the toFixed method the number would sometimes turn to a string.
I suggest next time read the dox a bit better https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed which says:
Returns
A string representation of number that does not use exponential
notation and has exactly digits digits after the decimal place. The
number is rounded if necessary, and the fractional part is padded with
zeros if necessary so that it has the specified length. If number is
greater than 1e+21, this method simply calls
Number.prototype.toString() and returns a string in exponential
notation.
My problem is really simple but I'm not sure if there's a "native" solution using JSON.parse.
I receive this string from an API :
{ "key" : -922271061845347495 }
When I'm using JSON.parse on this string, it turns into this object:
{ "key" : -922271061845347500 }
As you can see, the parsing stops when the number is too long (you can check this behavior here). It has only 15 exact digits, the last one is rounded and those after are set to 0. Is there a "native" solution to keep the exact value ? (it's an ID so I can't round it)
I know I can use regex to solve this problem but I'd prefer to use a "native" method if it exists.
Your assumption that the parsing stops after certain digits is incorrect.
It says here:
In JavaScript all numbers are floating-point numbers. JavaScript uses
the standard 8 byte IEEE floating-point numeric format, which means
the range is from:
±1.7976931348623157 x 10308 - very large, and ±5 x 10-324 - very small.
As JavaScript uses floating-point numbers the accuracy is only assured
for integers between: -9007199254740992 (-253) and 9007199254740992
(253)
You number lies outside the "accurate" range hence it is converted to the nearest representation of the JavaScript number. Any attempt to evaluate this number (using JSON.parse, eval, parseInt) will cause data loss. I therefore recommend that you pass the key as a string. If you do not control the API, file a feature request.
The number is too big to be parsed correctly.
One solution is:
Preprocessing your string from API to convert it into string before parsing.
Preform normal parsing
Optionally, you could convert it back into number for your own purpose.
Here is the RegExp to convert all numbers in your string (proceeded with :) into strings:
// convert all number fields into strings to maintain precision
// : 922271061845347495, => : "922271061845347495",
stringFromApi = stringFromApi.replace(/:\s*(-?\d+),/g, ': "$1",');
Regex explanation:
\s* any number of spaces
-? one or zero '-' symbols (negative number support)
\d+ one or more digits
(...) will be put in the $1 variable
I was wondering why do people have to convert numbers to string. What are the practical uses for that kind of conversion?
Similarly why do developers use parseInt or parseFloat to convert a string to a number.
thanks
The variable’s data type is the JavaScript scripting engine’s interpretation of the type of data that variable is currently holding. A string variable holds a string; a number variable holds a number value, and so on. However, unlike many other languages, in JavaScript, the same variable can hold different types of data, all within the same application. This is a concept known by the terms loose typing and dynamic typing, both of which mean that a JavaScript variable can hold different data types at different times depending on context.
With a loosely typed language, you don’t have to declare ahead of time that a variable will be a string or a number or a boolean, as the data type is actually determined while the application is being processed. If you start out with a string variable and then want to use it as a number, that’s perfectly fine, as long as the string actually contains something that resembles a number and not something such as an email address. If you later want to treat it as a string again, that’s fine, too.
The forgiving nature of loose typing can end up generating problems. If you try to add two numbers together, but the JavaScript engine interprets the variable holding one of them as a string data type, you end up with an odd string, rather than the sum you were expecting. Context is everything when it comes to variables and data types with JavaScript.
Using parseInt and parseFloat is important if you want to do arithmetic operations on a number which is in string form. For example
"42" + 1 === "421"
parseInt("42") + 1 === 43;
The reverse is true when you want to do string operations on values which are currently a number.
42 + 1 === 43
(42 + "") + 1 === 421
Why one would want to do the former or latter though is very scenario specific. I'd wager the case of converting strings to numbers for arithmetic operations is the more prominent case though.
An example of when converting numbers to strings is useful is when you want to format the number a certain way, perhaps like a currency (1234.56 -> $1,234.56).
The converse is useful when you want to do arithmetic on strings the represent numbers. Say you have a text box were you allow the user to input a number. The value of that text box will be a string, but you need it as a number to do some arithmetic with it, so you would use parseInt and parseFloat.
string -> number:
Think about simple number validation using JS. if you can convert a string into a number, then you can validate that number before posting to a number, or for use in an arithmetic operation.
number -> string:
String concatenation mainly and display purposes. The language will most often use implicit conversion to convert the number into a string anyway, such as:
1 + " new answer has been posted"
Do remember, Javascript is a loosely typed language. This can hide a lot of implicit type-casting that is occurring.
I have an interesting question, I have been doing some work with javascript and a database ID came out as "3494793310847464221", now this is being entered into javascript as a number yet it is using the number as a different value, both when output to an alert and when being passed to another javascript function.
Here is some example code to show the error to its fullest.
<html><head><script language="javascript">alert( 3494793310847464221);
var rar = 3494793310847464221;
alert(rar);
</script></head></html>
This has completly baffeled me and for once google is not my friend...
btw the number is 179 more then the number there...
Your number is larger than the maximum allowed integer value in javascript (2^53). This has previously been covered by What is JavaScript's highest integer value that a Number can go to without losing precision?
In JavaScript, all numbers (even integral ones) are stored as IEEE-754 floating-point numbers. However, FPs have limited "precision" (see the Wikipedia article for more info), so your number isn't able to be represented exactly.
You will need to either store your number as a string or use some other "bignum" approach (unfortunately, I don't know of any JS bignum libraries off the top of my head).
Edit: After doing a little digging, it doesn't seem as if there's been a lot of work done in the way of JavaScript bignum libraries. In fact, the only bignum implementation of any kind that I was able to find is Edward Martin's JavaScript High Precision Calculator.
Use a string instead.
179 more is one way to look at it. Another way is, after the first 16 digits, any further digit is 0. I don't know the details, but it looks like your variable only stores up to 16 digits.
That number exceeds (2^31)-1, and that's the problem; javascript uses 32-bit signed integers (meaning, a range from –2,147,483,648 to 2,147,483,647). Your best choice is to use strings, and create functions to manipulate the strings as numbers.
I wouldn't be all too surprised, if there already was a library that does what you need.
One possible solution is to use a BigInt library such as: http://www.leemon.com/crypto/BigInt.html
This will allow you to store integers of arbitrary precision, but it will not be as fast as standard arithmetic.
Since it's to big to be stored as int, it's converted to float. In JavaScript ther is no explicit integer and float types, there's only universal Number type.
"Can't increment and decrement a string easily..."
Really?
function incr_num(x) {
var lastdigit=Number(x.charAt(x.length-1));
if (lastdigit!=9) return (x.substring(0,x.length-1))+""+(lastdigit+1);
if (x=="9") return "10";
return incr_num(x.substring(0,x.length-1))+"0";
}
function decr_num(x) {
if(x=="0") return "(error: cannot decrement zero)";
var lastdigit=Number(x.charAt(x.length-1));
if (lastdigit!=0) return (x.substring(0,x.length-1))+""+(lastdigit-1);
if (x=="10") return "9"; // delete this line if you like leading zero
return decr_num(x.substring(0,x.length-1))+"9";
}
Just guessing, but perhaps the number is stored as a floating type, and the difference might be because of some rounding error. If that is the case it might work correctly if you use another interpreter (browser, or whatever you are running it in)