I can't seem to find the correct formula for having two decimal places in my code. Right now, it's rounding to three decimal places when I click on the first option in regards to calculations (not that 3 decimal places means anything. But regardless of the result, it should round to 2 decimal places). This is my last attempt:
$('#a_is_valid').one('click', function(){
if ($('#code_promo').val() == 'promocode')
{$('#gtotal').val($('#gtotal').val()-($('#gtotal').val()-
(($('#gtotal').val()*.75)))).fixed(2);
}
})
Given a number (or string representing a number), why not just do this:
var number;
var output = (Math.round(number * 100) / 100).toFixed(2);
In your case, it looks like you'd want:
$('#a_is_valid').one('click', function(){
if ($('#code_promo').val() == 'promocode')
{$('#gtotal').val((Math.round($('#gtotal').val() * 75) / 100).toFixed(2));
Math.round (appropriately enough) rounds to the nearest integer, so you'll have to do a bit of magic. Multiply by 10^(number of decimal places you want) - in your case, 10^2 or 100, round, and then divide by the same number.
In the example I made specifically for you, you'll notice I multiply by 75: 0.75 * 100.
It might be easiest to see this using a function:
function roundToNPlaces(n, val) {
var multiplier = Math.pow(10, n);
return (Math.round(val * multiplier) / multiplier).toFixed(n);
}
Then you could simply set your gtotal as follows:
$('#gtotal').val(roundToNPlaces(2, $('gtotal').val() * 0.75));
See this FIDDLE.
See:
Math.round NOTE: This documentation provides an implementation similar to (but more complex than) the code I gave. If you copy their entire Decimal rounding example in to your code (before the first time you need to use it), you can then just use Math.round10($('#gtotal').val() * .75, -2);. See http://jsfiddle.net/aW44n/1/
toFixed
Related
I have a some JavaScript that I use to calculate a percentage discount on a form field that holds a total value.
var thirteen = 10;
var percent_discount = (thirteen) * 0.01;
var percent_discount_final = (382.50 * (percent_discount));
console.log(percent_discount_final.toFixed(2));
The calculation is outputted at 38.24??
Why is that happening?
Well, should be the full value minus the discount - third line being:
var percent_discount_final = value_of_some_form_field - (value_of_some_form_field * percent_discount);
You almost figured out the right multiplier, but you forgot to subtract from 1, so you are multiplying by 0.1 instead of 0.9.
Here is an example of how to subtract any percentage from a number.
const subtractPercent = (value, percentage) => {
const multiplier = 1 - (percentage / 100);
return value * multiplier;
};
subtractPercent(250, 10); // 225
subtractPercent(250, 3); // 242.5
Similar to yours, this function assumes that value is positive, for simplicity's sake. Negative values will add instead of subtract.
subtractPercent(250, -10); // 275
subtractPercent(-250, 10); // -225
fun fact - float type is not precise. it came from large numbers theory, and by design it is approximation. that is why several languages provide also types like monetary etc. and for languages that don't, we calculate all monetary stuff on integers. it's not javascript related "bug", it is computer science "feature" :)
how to calculate monetary stuff on integers? well, you have to create/emulate new type. general idea is
convert all data from float to integer multiplying also by 100
perform all calculations on integers (no single float can be mixed, or the result will also be converted to float)
at the end (in most cases it's on data output / user interface) divide every value by 100
yes, in 21 century it looks plain stupid, but there is no magic you can use, when your tool (JS) doesn't have dedicated data type for monetary calculations. you have to build it.
is JS the only language involved in this project? if there is some for example some SQL db, most of them have dedicated monetary types, so you can make all your calculations on database side.
I have a JavaScript calculator which uses the Math.cbrt() function. When I calculate the cube root of 125 it returns 4.999999999999999. I understand that I could use Math.round() to round any answers that this function returns to integer values, but I do not want to do that exactly. Is there a way to use this if and only if the result of calculation is some number followed by a string of 9s (or something similar like 4.99999998 perhaps) after the decimal?
What you are dealing with is the frustration of floating point numbers in computing. See the Floating Point Guide for more information on this critical topic.
The short version:
Certain non-integer values cannot be represented accurately by computers, so they store a value that is "near enough". Just try evaluating 3.3 / 3 in your favourite REPL.
Say what?!
Computers are supposed to be perfect at this numbers/math thing, right? Can I trust any answer they give me?
Yes, for integers, they are pretty much perfect. But for non-integer calculations, you should assume that answers won't be exact, and account for these floating point errors.
The solution in Javascript
In newer versions of Javascript, you have a defined constant Number.EPSILON, which is the smallest difference between the actual number and the approximation that it can actually store.
Using this, you can multiply that constant by the result you get and add it to the result and you should get the exact value you require.
function cbrt(n) {
return Math.cbrt(n) + (Number.EPSILON * Math.cbrt(n));
}
Alternatively, you can use the rounding behaviour of the .toFixed() method on numbers together with the parseFloat() function if you only care about numbers up to a certain number of decimal places (less than 20).
function num(n, prec) {
if (prec === void 0) prec = 8; // default to 8 decimal places
return parseFloat(n.toFixed(prec));
}
var threshold = 0.999; // set to whatever you want
var fraction = result % 1;
if (fraction >= threshold) {
result = Math.round(result);
}
I am trying to Math.floor a scientific notation, but at one point the number gets too big and my current method doesn't work anymore. This is what I am using atm
var nr = (number+"").length - 4;
if( nr > 1 ) {
nr = Math.pow( 10, nr );
number= Math.floor(number/nr)*nr;
number= number.toExponential(3);
}
When it becomes a scientific notation by default, I think that's e20+, than my .length method doesn't work anymore since the length it returns isn't accurate. I can think of a work around, and that's to find out the number after e, and update my nr to Math.floor it properly, but it seems like so much work to do something so simple. Here's an example number 8.420960987929105e+79 I want to turn this into 8.420e+79, is there a way I can Math.floor the third decimal point always, no matter what the number is? As it stands when I use toExponential(3) it always rounds the number. My numbers can get as high as e+200 easily, so I need an easier way of doing what I'm currently doing.
Edit: managed to find a work around that works besides Connor Peet's answer for anyone who wants extra options
var nr = 8.420960987929105e+79+"";
var nr1 = nr.substr(0,4);
var nr2 = nr.substr(4, nr.length);
var finalNr = Number(nr1 + 0 + nr2).toExponential(3);
This way is more of a hack, it adds a 0 after the 4th number so when toExponential rounds it up, it gets 'floored' pretty much.
I wrote a little snippet to round a number to a certain number of significant figures some time ago. You might find it useful
function sigFigs(num, figures) {
var delta = Math.pow(10, Math.ceil(Math.log(num) / Math.log(10)) - figures);
return Math.round(num / delta) * delta;
}
sigFigs(number, 3); // => 8.420e+79
For instance, I have float 1.1111111111 and need to get 11111111111 and 10.
I want to avoid functions, which may change part after point as I need it to show metric prefixes.
It may look simple with strings, I am just not sure if it is a proper way in JavaScript.
The modular division operator '%' can be used to get the remainder of a division in JS. This means that if we perform the modular division of a floating point number by 1, we get the value after the decimal point. Further, if we build a loop where we multiply by 10 until there is no longer anything after the decimal point, we can find the smallest power of ten we can multiply the original number by to get an integer.
Example below:
function getE(floatingPointValue)
{
var x = floatingPointValue;
var digitsAfterDecimal = 0;
while(x % 1 != 0)
{
x = x * 10;
digitsAfterDecimal++;
}
return x.toString() + " *10^-" + digitsAfterDecimal;
}
Fiddle: http://jsfiddle.net/L8XtP/2/
Hope this helps!
How can I round the number using jQuery?
If the number is 3168 I want to print it as 32.
Or if the number is 5233 the result should be 52.
How can I do that?
Should I use the Math.round function?
Yes, you should use Math.round (after dividing by 100).
jQuery is a library for DOM traversal, event handling and animation built on top of JavaScript. It doesn't replace JavaScript and doesn't reimplement all its basic functions.
var num = 3168;
$('#myElement').text(Math.round(num/100));
I assume you mean divide by 100, then round? Or did you mean to have decimal places? (In which case, remove the /100 portion)
Also, this is just basic JavaScript. As another user mentioned, jQuery is to work with the document itself, not to perform math operations.
And here is a snippet from the jQuery math library1:
(function($){
$.round = Math.round;
})(jQuery);
$.round(3168 / 100) // 32
$.round(5233 / 100) // 52
1 Meant for humor only--this kind of functionality is provided out-of-the-box by JavaScript itself.
<script type='text/javascript'>
function jqROund(a) {
return Math.round(a/100);
}
</script>
<input type='text' id='numba' value='3168'>
<input type='button' onclick="alert( jqRound($('#numba').val() ) );">
The Math.round method does exactly you want and does not only ceil, or floor. It will round it to the nearest Integer.
If you're using the javascript Number object you can use the toFixed() method. I'm assuming those numbers are missing the decimal point. If not, divide by 100 and as above.
You can use this one :) roundMe(1.2345, 4)
function roundMe(n, sig) {
if (n === 0) return 0;
var mult = Math.pow(10, sig - Math.floor(Math.log(n < 0 ? -n: n) / Math.LN10) - 1);
return Math.round(n * mult) / mult;
}