I am writing a Javascript function where strings with apostrophe ( ' ) are not being displayed. Is there a way I can go around this? The below function assumes x is a string.
function addItem(x, y) //adds item on screen and adds Total
{
var newRow = "<tr><td>"+x+"</td><td>€"+y.toFixed(2)+"</td><td><input type=\"button\" onclick=\"subtract("+y+")\" value = \"X\"></td></tr>"
$('#order').append(newRow);
document.getElementById("currentorder").value += newRow;
//Adds Total Value
var total = document.getElementById('price').innerHTML;
total = parseFloat(total);
var z = +y + +total;
document.getElementById('price').innerHTML=z.toFixed(2);
event.preventDefault();
}
Confusing Addition Operators
The following line looks quite a bit off :
var z = +y + +total;
If you just want to add y and total, just simplify it as :
var z = y + total;
Consider Possible Parsing Errors
Another idea would be to consider stripping out any non float related characters (i.e. non decimals and digits) within your string prior to calling your parseFloat() function :
var total = parseFloat(document.getElementById('price').innerHTML.replace(/[^\d\.]/g,''));
Related
So i made a function that calculate the price by multiplication how many meters i put the problem is when ever i put decimal numbers it ignores it
heres my script
<script>
function getFillingPrice() {
cake_prices = document.getElementById('price').value;
filling_prices = document.getElementById('test2').value;
var t=parseInt(filling_prices);
var x=parseInt(cake_prices);
return t*x;
}
function calculateTotal() {
var total = getFillingPrice();
var totalEl = document.getElementById('totalPrice');
document.getElementById('test3').value =total + " دينار ";
totalEl.style.display = 'block';
}
</script>
You're converting the values to integers when you get them from the DOM.
Change this...
var t=parseInt(filling_prices);
var x=parseInt(cake_prices);
to this...
var t=parseFloat(filling_prices);
var x=parseFloat(cake_prices);
Beside the parsing problem, you could use
an unary plus + and
a default value for non parsable value, like letters or an empty string (falsy values) with a logical OR ||.
cake_price = +document.getElementById('price').value || 0
// ^ unary plus for converting to numbner
// ^^^ default value for falsy values
Together
function getFillingPrice() {
var cake_price = +document.getElementById('price').value || 0,
filling_price = +document.getElementById('test2').value || 0;
return cake_price * filling_price;
}
How can I construct a float value from two whole values?
var amountBeforeComma = 5;
var amountAfterComma = 234;
var amount = ?? //amount == 5.234
There's the math way, using logarithms:
var amountBeforeComma = 5;
var amountAfterComma = 234;
var amount = amountBeforeComma +
amountAfterComma * Math.pow(10, -(Math.floor(Math.log10(amountAfterComma)) + 1));
console.log(amount);
Math.log10(amountAfterComma) gives us the common logarithm of amountAfterComma, then Math.floor(...) on that gives us the characteristic of it (2 in your example), which is (as the linked Wikipedia page puts it) "how many places the decimal point must be moved so that it is just to the right of the first significant digit". Then we add one to that and make it a negative (e.g., -3 in your example) and raise raise 10 to that power to get a value to multiply it by (0.001 in your example) to put it where it should go. Add the amountBeforeComma and we're done.
Or the string then parse way:
var amountBeforeComma = 5;
var amountAfterComma = 234;
var amount = parseFloat(amountBeforeComma + "." + amountAfterComma);
console.log(amount);
(Or use +(amountBeforeComma + "." + amountAfterComma) to convert with implicit coercion rather than explicit parsing.)
Since no one mentioned... There's the JavaScript way:
var num = +(amountBeforeComma + "." + amountAfterComma);
You can make it by casting numbers to strings and then parsing it as float.
var amount = parseFloat(amountBeforeComma + '.' + amountAfterComma);
I am making a calculator in JavaScript and I want to know how to turn a string into an expression.
var numbers = "5+5+6";
numbers = +numbers;
document.querySelector('.screen').innerHTML = numbers;
Adding + before the variable does not seem to work. I would appreciate it if someone helped.
You can use the eval() function like this:
var numbers = "5+5+6";
document.querySelector('.screen').innerHTML = eval(numbers);;
Evaluate/Execute JavaScript code/expressions:
var x = 10;
var y = 20;
var a = eval("x * y") + "<br>";
var b = eval("2 + 2") + "<br>";
var c = eval("x + 17") + "<br>";
var res = a + b + c;
The result of res will be:
200
4
27
Without using eval, which is cheating - you could always write a simple calculator app.
First, take advantage of String.split() as follows
var numbers = "5+5+6";
numbers.split("");
// => ["5","+","5","+","6"]
Now all you need to do is figure out how to evaluate it while keeping the order of operations correct. Hint: it might involve trees.
Try using String.prototype.match() , Array.prototype.reduce() , Number() . See also Chrome App: Doing maths from a string
var numbers = "5+5+6";
var number = numbers.match(/\d+|\+\d+|\-\d+/g)
.reduce(function(a, b) {
return Number(a) + Number(b)
});
document.querySelector(".screen").innerHTML = number;
<div class="screen"></div>
I have 2 numbers
a = 1548764548675465486;
b = 4535154875433545787;
when I sum these number they are rounded to
a => 1548764548675465500
b => 4535154875433545700
and a + b returns 6083919424109011000 while it should return 6083919424109011273
is there a javascript solution to solve this problem witout the use of a library ?
To work around the precision limitations associated with JavaScript's numbers, you will need to use a BigInteger library like the popular one offered here: http://silentmatt.com/biginteger/
Usage:
var a = BigInteger("1548764548675465486");
var b = BigInteger("4535154875433545787");
var c = a.add(b);
alert(a.toString() + ' + ' + b.toString() + ' = ' + c.toString());
// Alerts "1548764548675465486 + 4535154875433545787 = 6083919424109011273"
Demo: http://jsfiddle.net/69AEg/1/
There are no integers in Javascript, all numbers are double precision floating point.
That gives you a precision of around 15-16 digits, which is what you are seeing.
as per this question
and potential solution i.e. use a library
Personally, I would not use javascript, never been great at numbers. Just try typing 0.1 + 0.2 into any browsers console window. Result is 0.30000000000000004.
Send the calculation to your server side language (as a string) and do the work there, you should have a better outcome.
Technical article on the nuances of floating point numbers here, if you interested
Well, here is a solution I found witout the use of any external library, all I need to do is to define a class that had a property value wich should be a string, and define the function plus
function LongNumber()
{
// it takes the argument and remove first zeros
this.value = arguments[0].toString();
while(this.value[0]==="0")
this.value = this.value.substr(1);
// this function adds the numbers as string to another string and returns result as LongNumber
this.plus = function (Num)
{
var num1 = pad(Num.value.length, this.value);
var num2 = pad(this.value.length, Num.value);
var numIndex = num1.length;
var rest = 0;
var resultString = "";
while (numIndex)
{
var number1 = parseInt(num1[(numIndex)-1]);
var number2 = parseInt(num2[(numIndex--)-1]);
var addition = (number1+number2+rest)%10;
rest = parseInt((number1+number2+rest)/10);
resultString = addition.toString() + resultString;
}
return new LongNumber((rest?rest.toString():"") + resultString);
}
function pad(width, string)
{
return (width <= string.length) ? string : pad(width, '0' + string)
}
}
All i need to do now is to declare 2 LongNombers and use the function plus
var Number1 = new LongNumber("1548764548675465486");
var Number2 = new LongNumber("4535154875433545787");
var Result = Number1.plus(Number2);
Result.value // returns "6083919424109011273"
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.