Javascript GUID (Global Unique Identifier) Generator Explanation - javascript

I'm trying to write a JavaScript GUID generator for 8 characters including lowercase / uppercase letters, numbers and symbols. I found these solutions but need an explanation on what is happening in each. Originally I thought I'd need a string holding all the letters/numbers/symbols that I would index into with random number function to build a new GUID, but these solutions seem to create numbers/letters/symbols out of thin air.
In solution 1, what is the purpose of "1+" and "0x10000"? What is the purpose of ".toString(16)" and ".substring(1)" and how is it generating numbers/symbols/AND letters with just that little bit of code?
Solution 1:
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
In solution 2, I see how the GUID is 32 characters long but don't understand why Math.Random is being multiplied by specifically "16", with a toString(16) attached but no ".substring(x)" this time?
Solution 2:
function generateGuid() {
var result, i, j;
result = '';
for(j=0; j<32; j++) {
if( j == 8 || j == 12|| j == 16|| j == 20)
result = result + '-';
i = Math.floor(Math.random()*16).toString(16).toUpperCase();
result = result + i;
}
return result;
}
No need to explain the structure of a GUID nor what is a hyphen is XD
Any and all detailed explanations are appreciated!

In the 2nd case Math.random() would generate a number which lies between 0(inclusive) to 1(exclusive).
Now if I want a number which should be < 16, multiplying 16 with a value in [0, 1) should do the job for me, toString(16) converts it into a digit of base 16. We add 32 such digits overall
The 1st example generates a number between (1.0, 2.0] and multiplies it with (10^4) to the base 16. Now we have a number in the range (10000, 20000] base 16.
taking the last 4 digits should suffice for us so we take the relevant substring out of it.
That being the case I think
Math.floor((Math.random()) * 0x10000)
.toString(16)
would also suffice for that solution, since we need a 4 digit hexa number

Related

Does parseInt return a strict integer?

My understanding was that javascript doesn't strictly speaking have an integer datatype, but I'm coming across a weird problem that's having me second guess myself.
I'm trying to build a simple custom rounding function using parseInt to drop extra decimal places, but the full function always returns an integer:
function round(num, places){
return (parseInt(num*10^places) + 0.5)/10^places
}
For completeness, I'm using this function within another:
function convertDegrees(val, uom){
if (uom === "celcius"){
return round(val * 9/5 + 32, 2) + " degrees Fahrenheit"}
else {
return round((val - 32) * 5/9, 2) + " degrees Celcius"}
}
But I don't see what in that would cause the problem either.
It looks like you want to raise something to an exponent which needs ** not ^ which is bitwise XOR
function round(num, places) {
return (parseInt(num * 10 ** places) + 0.5) / 10 ** places
}
function convertDegrees(val, uom) {
if (uom === "celcius") {
return round(val * 9 / 5 + 32, 2) + " degrees Fahrenheit"
} else {
return round((val - 32) * 5 / 9, 2) + " degrees Celcius"
}
}
console.log(convertDegrees(0, 'celcius'))

JavaScript - Convert 24 digit hexadecimal number to decimal, add 1 and then convert back?

For an ObjectId in MongoDB, I work with a 24 digit hexadecimal number. Because I need to keep track of a second collection, I need to add 1 to this hexadecimal number.
In my case, here's my value
var value = "55a98f19b27585d81922ba0b"
What I'm looking for is
var newValue = "55a98f19b25785d81922ba0c"
I tried to create a function for this
function hexPlusOne(hex) {
var num = (("0x" + hex) / 1) + 1;
return num.toString(16);
}
This works with smaller hex numbers
hexPlusOne("eeefab")
=> "eeefac"
but it fails miserably for my hash
hexPlusOne(value)
=> "55a98f19b275840000000000"
Is there a better way to solve this?
This version will return a string as long as the input string, so the overflow is ignored in case the input is something like "ffffffff".
function hexIncrement(str) {
var hex = str.match(/[0-9a-f]/gi);
var digit = hex.length;
var carry = 1;
while (digit-- && carry) {
var dec = parseInt(hex[digit], 16) + carry;
carry = Math.floor(dec / 16);
dec %= 16;
hex[digit] = dec.toString(16);
}
return(hex.join(""));
}
document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("ffffffffffffffffffffffff"));
This version may return a string which is 1 character longer than the input string, because input like "ffffffff" carries over to become "100000000".
function hexIncrement(str) {
var hex = str.match(/[0-9a-f]/gi);
var digit = hex.length;
var carry = 1;
while (digit-- && carry) {
var dec = parseInt(hex[digit], 16) + carry;
carry = Math.floor(dec / 16);
dec %= 16;
hex[digit] = dec.toString(16);
}
if (carry) hex.unshift("1");
return(hex.join(""));
}
document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("ffffffffffffffffffffffff"));
I was curious te see whether user2864740's suggestion of working with 12-digit chunks would offer any advantage. To my surprise, even though the code looks more complicated, it's actually around twice as fast. But the first version runs 500,000 times per second too, so it's not like you're going to notice in the real world.
function hexIncrement(str) {
var result = "";
var carry = 1;
while (str.length && carry) {
var hex = str.slice(-12);
if (/^f*$/i.test(hex)) {
result = hex.replace(/f/gi, "0") + result;
carry = 1;
} else {
result = ("00000000000" + (parseInt(hex, 16) + carry).toString(16)).slice(-hex.length) + result;
carry = 0;
}
str = str.slice(0,-12);
}
return(str.toLowerCase() + (carry ? "1" : "") + result);
}
document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("000000000000ffffffffffff") + "<BR>");
document.write(hexIncrement("0123456789abcdef000000000000ffffffffffff"));
The error comes from attempting to covert the entire 24-digit hex value to a number first because it won't fit in the range of integers JavaScript can represent distinctly2. In doing such a conversion to a JavaScript number some accuracy is lost.
However, it can be processed as multiple (eg. two) parts: do the math on the right part and then the left part, if needed due to overflow1. (It could also be processed one digit at a time with the entire addition done manually.)
Each chunk can be 12 hex digits in size, which makes it an easy split-in-half.
1 That is, if the final num for the right part is larger than 0xffffffffffff, simply carry over (adding) one to the left part. If there is no overflow then the left part remains untouched.
2 See What is JavaScript's highest integer value that a Number can go to without losing precision?
The range is 2^53, but the incoming value is 16^24 ~ (2^4)^24 ~ 2^(4*24) ~ 2^96; still a valid number, but outside the range of integers that can be distinctly represented.
Also, use parseInt(str, 16) instead of using "0x" + str in a numeric context to force the conversion, as it makes the intent arguably more clear.

Why does parseInt('dsff66',16) return 13?

today I stumbled on a strange (in my opinion) case in JavaScript. I passed a non-hexadecimal string to the parseInt function with the base of 16 and...I got the result.
I would expect the function to throw some kind of exception or at least return NaN, but it succeeded parsing it and returned an int.
My call was:
var parsed = parseInt('dsff66', 16); // note the 's' in the first argument
document.write(parsed);
and the result was: 13.
I noticed that it "stops" parsing with the first character that doesn't belong to the numeral system specified in the 2nd argument, so calling parseInt('fg',16) I would get 15 as a result.
In my opinion, it should return NaN. Can anyone explain to me why it doesn't? Why would anyone want this function to behave like this (return an integer even if it isn't the precise representation of the string passed) ?
parseInt reads input until it encounters an invalid character, and then uses whatever valid input it read prior to that invalid character. Consider:
parseInt("17days", 10);
This will use the input 17 and omit everything after the invalid d.
From the ECMAScript specification:
If [input string] S contains any character that is not a radix-R digit, then let Z [the string to be integer-ified] be the substring of S consisting of all characters before the first such character; otherwise, let Z be S.
In your example, s is an invalid base-16 character, so parseInt uses only the leading d.
As for why this behavior was included: there's no way to know for sure, but this is quite likely an attempt to reproduce the behavior of strtol (string to long) from C's standard library. From the strtol(3) man page:
...the string is converted to a long int value in the obvious manner, stopping at the first character which is not a valid digit in the given base.
This connection is further supported (to some degree) by the fact that both parseInt and strtol are specified to ignore leading whitespace, and they can both accept a leading 0x for hexadecimal values.
Why would anyone want this function to behave like this (return an integer even if it isn't the precise representation of the string passed)?
Because most of the time (by far) you're working with base 10 numbers, and in that case JS can just cast - not parse - the string to a number. (edit: Apparently not just base-10; see update below.)
Since JS is dynamically typed, some strings work just fine as numbers without any work on your part. For instance:
"21" / 3; // => 7
"12.4" / 4; // => 3.1
No need for parseInt there, because "21" and "12.4" are essentially numbers already. If, however the string was "12.4xyz" then you would indeed get NaN when dividing, since that is decidedly not a number and can't be implicitly cast or coerced to one.
You can also explicitly "cast" a string to number with Number(someString). While it too only supports base 10, it will indeed return NaN for invalid strings.
So because JS already has implicit and explicit type casting/conversion/coercion, parseInt's role isn't to be a yet another type casting function.
parseInt's role is instead to be, well, a parsing function. A function that tries its best to make sense of its input, returning what it can. It's for when you have a string you can't just cast because it's not quite perfectly numeric. (And, like JS's basic syntax, it's reminiscent of C, as apsillers' answer explained nicely.)
And since it's a parser, not a casting function, it's got the additional feature of being able to handle other bases than 10.
Now, you might ask why there isn't a strict casting function that handles non-base-10 numbers, and would complain like you want, but... hey, there just isn't. JS's designers just decided that parseInt would suffice, because, again, 0x63 percent of the time, you're dealing with base 10.
Closest you can get to "casting" is probably something horribly hacky like:
var hexString = "dsff66";
var number = eval("0x" + hexString); // attempt to interpret as a hexadecimal literal
which'll throw a SyntaxError because 0xdsff66 isn't a valid hex literal.
Update: As Lekensteyn points out in the comments, JS appears to properly cast 0x-prefixed hexadecimal strings too. I didn't know this, but indeed this seems to work:
1 * "0xd0ff66"; // => 13696870
1 * "0xdsff66"; // => NaN
which makes it the simplest way to cast a hex string to a number - and get NaN if it can't be properly represented.
Same behavior applies to Number(), e.g Number("0xd0ff66") returns an integer, and Number("0xdsff66") returns NaN.
(/update)
Alternatively, you can check the string beforehand and return NaN if needed:
function hexToNumber(string) {
if( !/^(0x)?[0-9a-f]+$/i.test(string) ) return Number.NaN;
return parseInt(string, 16);
}
In this particular case parseInt() interpret letter from "A" to "F" as hexadecimal and parse those to decimal numbers. That means d will return 13.
What parseInt() does
parseInt("string", radix) interpret numbers and letters in the string as hexadecimal (it depend on the radix) to number.
parseInt() only parse number or letter as hexadecimal from the beginning of the string until invalid character as hexadecimal.
If parseInt() can't find any number or letter as hexadecimal at the beginning of the string parseInt() will return NaN.
If the radix is not defined, the radix is 10.
If the string begin with "0x", the radix is 16.
If the radix defined 0, the radix is 10.
If the radix is 1, parseInt() return NaN.
If the radix is 2, parseInt() only parse "0" and "1".
If the radix is 3 , parseInt() only parse "0", "1", and "2". And so on.
parseInt() parse "0" to 0 if there is no number follows it as the result and remove 0 if there is number follows it. e.g. "0" return 0 and "01" return 1.
If the radix is 11, parseInt() only parse string that begins with number from "0" to "9" and/or letter "A".
If the radix is 12, parseInt only parse string that begins with number from "0" to "9" and/or letter "A" and "B", and so on.
the maximum radix is 36, it will parse string that begins with number from "0" to "9" and/or letter from "A" to "Z".
If the characters interpreted as hexadecimal more than one, every characters will has different value, though those characters are the same character. e.g. parseInt("AA", 11) the first "A" has different value with the second "A".
Different radix will return different number though the strings is the same string.
See it in action
document.body.innerHTML = "<b>What parseInt() does</b><br>" +
"parseInt('9') = " + parseInt('9') + "<br>" +
"parseInt('0129ABZ', 0) = " + parseInt('0129ABZ', 0) + "<br>" +
"parseInt('0', 1) = " + parseInt('0', 1) + "<br>" +
"parseInt('0', 2) = " + parseInt('0', 2) + "<br>" +
"parseInt('10', 2) = " + parseInt('10', 2) + "<br>" +
"parseInt('01', 2) = " + parseInt('01', 2) + "<br>" +
"parseInt('1', 2) = " + parseInt('1', 2) + "<br>" +
"parseInt('A', 10) = " + parseInt('A', 10) + "<br>" +
"parseInt('A', 11) = " + parseInt('A', 11) + "<br>" +
"parseInt('Z', 36) = " + parseInt('Z', 36) + "<br><br>" +
"<b>The value:</b><br>" +
"parseInt('A', 11) = " + parseInt('A', 11) + "<br>" +
"parseInt('A', 12) = " + parseInt('A', 12) + "<br>" +
"parseInt('A', 13) = " + parseInt('A', 13) + "<br>" +
"parseInt('AA', 11) = " + parseInt('AA', 11) + " = 100 + 20" + "<br>" +
"parseInt('AA', 12) = " + parseInt('AA', 12) + " = 100 + 30" + "<br>" +
"parseInt('AA', 13) = " + parseInt('AA', 13) + " = 100 + 40" + "<br>" +
"parseInt('AAA', 11) = " + parseInt('AAA', 11) + " = 1000 + 300 + 30" + "<br>" +
"parseInt('AAA', 12) = " + parseInt('AAA', 12) + " = 1000 + 500 + 70" + "<br>" +
"parseInt('AAA', 13) = " + parseInt('AAA', 13) + " = 1000 + 700 + 130" + "<br>" +
"parseInt('AAA', 14) = " + parseInt('AAA', 14) + " = 1000 + 900 + 210" + "<br>" +
"parseInt('AAA', 15) = " + parseInt('AAA', 15) + " = 1000 + 1100 + 310";
For radices above 10, the letters of the alphabet indicate numerals greater than 9. For example, for hexadecimal numbers (base 16), A through F are used.
In your string dsff66, d is a hexadecimal character(even though the string is non hex) which fits the radix type and is equivalent to number 13. It stops parsing after that since next character is not hexadecimal hence the result.

Rounding to Significant Figures - Missing Zeros

I'm currently producing a JavaScript driven mathematics package, which focuses on rounding to various significant figures (S.F.) but I've run into a problem that I'm struggling to solve.
More on this problem later, but first some background for you.
The program is designed to select a completely random number within a given range and then automatically work out that number's relevant significant figures; for example:
Random Number: 0.097027 S.Fs: 9, 7, 0, 2, 7
Here is a screenshot of what I have produced to give you a visual representation:
As you can see, once the user has selected their number, they are then given the opportunity to click on four separate 'SF' buttons to view their random number presented to 1, 2, 3 and 4 S.Fs respectively.
For each S.F (1-4) the random number is rounded down, rounded up and rounded off to X SF and a scale below gives the user a more visual presentation to show why the SF value has been chosen by the program.
I've already written the vast majority of the code for this and tested it and so far the numbers are coming out how I'm expecting them to. Well nearly...
In the example I've given (0.097027); as you can see on the image I've included, the data for 4 S.F is absolutely correct and outputted accurately.
When I click on to the 3 SF button, I'd expect to see the following:
Random Number: 0.097027 3 S.F Rounded Up/Down/Off: 0.0970
However, what I'm actually getting is:
Random Number: 0.097027 3 S.F Rounded Up/Down/Off: 0.097
The program hasn't displayed the additional zero. This is a perfect example of a number in my program ending in a zero and in this case the zero is really significant and must be displayed.
The data is usually correct but there appears to be an issue with outputting significant zeros at the right time. I've researched the toFixed(x) method and if I assign toFixed(4) I get the correct required output, but because my numbers are generated randomly each time, they can range from a length of 5 figures, e.g. 89.404 up to > 10, e.g. `0.000020615.
So it looks like the toFixed method needs to be flexible/dynamic, e.g. toFixed(n) with a function run beforehand to determine exactly how many trailing zeros are needed?
Here are some key excerpts from my current solution for your consideration:
function generateNum() {
do {
genNumber = Math.random() * Math.pow (10, randomRange(-5, 5));
//Round
genNumber = roundToNSF(genNumber, 5, 0);
// This number must contain >1 digit which is 1 to 9 inclusive otherwise we may have e.g. 100. Rounding 100
}
while (!countNonZero(genNumber) || genNumber < 1E-05 || genNumber == 0);
//Round
genNumber = roundToNSF(genNumber, 5, 0);
genNumber = String(genNumber);
genNumber = Number(genNumber);
}
//----------------------------------------------------------------------------
function randomRange(min, max) {
/**
* Returns a random integer between min (inclusive) and max (inclusive)
* Using Math.round() will give you a non-uniform distribution!
*/
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//---------------------------------------------------------------------------
//Click SF3 Button to reveal the data
function showSF3() {
//Remove any CSS properties on the buttons from previous use
removeButtonCSS();
document.getElementById('SFRounded').style.display = "block";
document.getElementById('scale').style.display = "block";
document.getElementById("SF3").className = document.getElementById("SF3").className + "buttonClick"; // this removes the blue border class
//Clear text
deleteRounded();
deleteScale();
//Run calculation
calculateAnswer();
//alert(genNumber.toFixed(4));
for (i = 3; i < 4; i++)
{
//Add The new data
sfRoundedTextBlock = document.getElementById('SFRounded');
//alert(downArray[i].toFixed(4));
//Data output to HTML.
sfRoundedTextBlock.innerHTML = sfRoundedTextBlock.innerHTML + '<p><strong>Number: </strong></br>' + String(genNumber) +
'</br>' + '<strong>Rounded down to ' + i + ' SF:</br></strong>' + downArray[i] + '</br>' +
'<strong>Rounded up to ' + i + ' SF:</br></strong>' + upArray[i] + '</br><strong>Rounded off to ' + i + ' SF:</br></strong>'
+ roundedArray[i] + '</br>' + '(See the scale below for why we choose <strong>' + roundedArray[i] + '</strong> as the rounded off value.)</p>';
}
}
//----------------------------------------------------------------------
var roundedArray = [];
var upArray = [];
var downArray = [];
var temp;
function calculateAnswer() {
//Clear Arrays
roundedArray = [];
upArray = [];
downArray = [];
// Work out the answer:
for (i = 0; i < 4; i++) {
var nSF = i + 1;
// Round OFF ...
temp = roundToNSF(genNumber, nSF, 0);
// We actually have to do this twice ...
roundedArray[nSF] = roundToNSF(temp, nSF, 0);
// Round UP ...
upArray[nSF] = roundToNSF(genNumber, nSF, 1);
// Round DOWN ...
downArray[nSF] = roundToNSF(genNumber, nSF, -1);
// e.g. x = 0.0098 rounded to 1SF is 0.010 initially (take the log of 0.0098 and try it!).
};
};
//-------------------------------------------------------------------------
//Globals
var aNumber;
var digits;
var way;
function roundToNSF(aNumber, digits, way){
// Round a number to n significant figures (can use roundToNDP provided we know how many decimal places):
if (way == undefined) { way = 0; }; // default is round off
if (aNumber !=0) {
if (aNumber > 0)
{
z = log10(aNumber);
}
else
{
z = log10(-aNumber);
};
z = Math.floor(z);
var nDP = digits - z - 1; // Rounding to nDP decimal places is equivalent to rounding to digits significant figures ...
var roundedNumber = roundToNDP(aNumber, nDP, way);
}
else {
roundedNumber = aNumber; // Number is zero ...
};
return Number(roundedNumber);
};
//---------------------------------------------------------------------------------
Update:
I'm still continuing to try and find a solution for this problem and an approach I have recently taken is to convert my randomly generated number into a searchable string variable and then use the indexOf(".") command to find the position of the decimal point (dp).
Then I've searched through my number, starting from the position of the dp to find the first instance of a significant, non-zero number [1-9].
var genNumber = 0.097027;
var rString = String(genNumber);
var positionofDP = rString.indexOf(".");
var regexp = /[1-9]/;
var positionofNonZero = Number(rString.search(regexp, positionofDP)); // Output would be '5'
I have then been able to target my search further, to determine whether my first significant number has any 'problematic' zeros in the immediate digits after it.
If there are any, then I set a Boolean variable to 'true' and then in a separate function create further text strings of my rounded off/down/up numbers, so I can then physically choose to add a '0' on to the end of the existing numerical characters.
This approach does work for me in isolated cases, but with my random number length ranging from 5-12 digits long, it still isn't dealing with all scenarios.
Maybe I need to create a dynamic toFixed(i) function? Any ideas would be greatly welcomed.
Instead of playing with the fixed points on an Int, you could manage the string directly.
Here's a link to a little fiddle: http://jsfiddle.net/5rw5G/4/
This not intended to completely/accurately solve your problem, but might help you see another solution.
function getRoundedSFs(num, SFCount) {
// Match every "leading zeros" before and after the .
var matches = num.toString().match(/^-?(0+)\.(0*)/);
// starting with "0."
if (matches) {
var firstIndex = matches[0].length;
var prefix = matches[0];
sf = Number(num.toString().substring(firstIndex, firstIndex + SFCount + 1));
sf = Math.round(sf / 10);
sf = prefix + sf.toString();
return Number(sf).toFixed(matches[2].length+SFCount);
}
// starting with something else like -5.574487436097115
else {
matches = num.toString().match(/^(-?(\d+))\.(\d+)/);
var decimalShift = SFCount - matches[2].length;
var rounded = Math.round(num * Math.pow(10, decimalShift));
rounded /= Math.pow(10, decimalShift);
return rounded.toFixed(decimalShift);
}
}
I've gone away again and I think I have now finally managed solve my initial problem.
There was a degree of confusion on my part surrounding when to use toFixed and toPrecision. I had previously attempted to convert my rounded up, down and off numbers into strings and then subsequently search through each of these to find the decimal point (".") and then work out the amount of trailing numbers, in order to then generate the correct toFixed point.
However, this was very hit and miss, given that my random number could be up to 12 digits, so what I've now done is to properly utilise toPrecision instead. For each 'SF button' (1-4) I have used the corresponding toPrecision point, e.g for SF1:
sfRoundedTextBlock.innerHTML = sfRoundedTextBlock.innerHTML + '<p><strong>Number: </strong></br>' + String(genNumber) +
'</br>' + '<strong>Rounded down to ' + i + ' SF:</br></strong>' + downArray[i].toPrecision(1) + '</br>' +
'<strong>Rounded up to ' + i + ' SF:</br></strong>' + upArray[i].toPrecision(1) + '</br><strong>Rounded off to ' + i + ' SF:</br></strong>'
+ roundedArray[i].toPrecision(1) + '</br>' + '(See the scale below for why we choose <strong>' + roundedArray[i].toPrecision(1) + '</strong> as the rounded off value.)</p>';
//Add The new scale data (Rounded Down)
downTextBlock = document.getElementById('down');
document.getElementById("down").innerHTML = String(downArray[i].toPrecision(1));
//Add The new scale data (Rounded Up)
upTextBlock = document.getElementById('up');
document.getElementById("up").innerHTML = String(upArray[i].toPrecision(1));
This was now giving me accurate results on every occasion, but there was still one hurdle left to jump. Occasionally I would reach a random scenario where scientific notation would have to be included in my outputted answer, e.g. 21819 rounded down to 1 SF, would read out at 2e+4 instead of 20000.
To combat this I setup my up, down and rounded figures into searchable strings, and then looked through these to find any illegal/scientific characters [a-z]. If I found any, I executed a slightly different version of my output which made use of parseFloat, which stripped out the scientific notation and displayed the correct figures:
//Convert Up, Down and Rounded into Strings based on their precision
var upString = String(upArray[i].toPrecision(1));
var downString = String(downArray[i].toPrecision(1));
var roundedString = String(roundedArray[i].toPrecision(1));
//Set up a regexp to search for characters [a-z], i.e. non-numeric
var regexp = /[a-z]/g;
//Search the up, down and rounded strings for non-numeric characters
var upResult = upString.match(regexp);
var downResult = downString.match(regexp);
var roundedResult = roundedString.match(regexp);
//If any of these strings contain a letter (non-numeric) we need to add in parseFloat to strip away the scientific notation included.
var containsChar = false;
if (upResult != null || downResult != null || roundedResult != null)
{
containsChar = true;
//alert("There is SN included here");
}
//Add The new data
sfRoundedTextBlock = document.getElementById('SFRounded');
if (containsChar == true)
{
sfRoundedTextBlock.innerHTML = sfRoundedTextBlock.innerHTML + '<p><strong>Number: </strong></br>' + String(genNumber) +
'</br>' + '<strong>Rounded down to ' + i + ' SF:</br></strong>' + parseFloat(downArray[i].toPrecision(1)) + '</br>' +
'<strong>Rounded up to ' + i + ' SF:</br></strong>' + parseFloat(upArray[i].toPrecision(1)) + '</br><strong>Rounded off to ' + i + ' SF:</br></strong>'
+ parseFloat(roundedArray[i].toPrecision(1)) + '</br>' + '(See the scale below for why we choose <strong>' + parseFloat(roundedArray[i].toPrecision(1)) + '</strong> as the rounded off value.)</p>';
//Add The new scale data (Rounded Down)
downTextBlock = document.getElementById('down');
document.getElementById("down").innerHTML = String(parseFloat(downArray[i].toPrecision(1)));
//Add The new scale data (Rounded Up)
upTextBlock = document.getElementById('up');
document.getElementById("up").innerHTML = String(parseFloat(upArray[i].toPrecision(1)));
}
Having tested this extensively it seems to be working as hoped.

Trying to get my JavaScript to work out the 2 numbers entered to get calculated by pc.

Just wondering if anyone can work out why I keep getting for eg. 3+3=33 and not 6.
The rest of the coding works fine for the divide and times its the addition that keeps stuffing up and wont come up with the correct answer.. please help if you can.
here is my code:
<html>
<head>
<title>Practical Task 8 </title>
</head>
<body>
<button onclick="myFunction()">Press & Enter First Digit & Second Digit</button>
<script type="TEXT/JavaScript">
function myFunction()
{
var x=prompt("Please enter first number","0");
var y=prompt("Please enter second number","0");
var sum = x;
var sum2 = y;
var n = (x * y);
var n2 = (x / y);
var n3 = (x + y);
document.write(sum + " + " + sum2 + " = " + n3);
document.write("<BR>" + sum + " * " + sum2 + " = " + n);
document.write("<BR>" + sum + " / " + sum2 + " = " + n2);
}
</script>
</body>
</html>
You're performing string concatenation, not integer addition.
Use parseInt first:
x = parseInt( x, 10 );
y = parseInt( y, 10 );
MDN recommends always specifying the radix (the 10 part) to avoid problems, such as if a user prepends a number with 0 (where it'll be parsed as octal), or if different browsers have a different default radix (wtf, I know!).
You have to do this because the output of prompt is always a string, even if it's a number (e.g. "10" or "0123"), you need to tell JavaScript to interpret the data as a number (use parseInt if it's an integer (a whole number), or use parseFloat if you'll accept numbers with decimal places). Confusingly the + operator works for both string and number types, where it performs either concatenation (i.e. joining strings together like glue) or addition depending on the type of its operands.
Because your code is adding strings.
User input is always string.
You need to parseInt(x, 10) and parseInt(y, 10) to parse the string value into int base 10.

Categories