Find the sum of the digits in the number 100! in javascript - javascript

i am getting answer 659 but that one is wrong answer please check it one's.
this is my code
var fact=1;
for(var i=1;i<=100;i++){
fact = fact*i;
}
var sum = 0;
while (fact > 0) {
sum += fact % 10;
fact = Math.floor(fact / 10);
}
console.log(sum);

There's a syntax error in the definition of length - the var keyword should come before it, not after it, and a similar problem in the calculation of sum.
Regardless, I think that converting the number to a string is the hard way to go at it. You can use the % operator to get the last digit and divide the number by 10 (don't forget to floor!) until you're done with all the digits:
var sum = 0;
while (fact > 0) {
sum += fact % 10;
fact = Math.floor(fact / 10);
}

Cool. You've written a very sensible piece of code. But there are a couple things to think about. One is the gigantic size of 100!. If you go to a console and enter some code, you'll see this:
> fact=1
1
> for(i=1;i<=100;i++){fact *= i;}
9.33262154439441e+157
Crikey. 10 to the 157. Look up the largest integer js can display. It's much smaller! So if this is a programming assignment, you have to be more subtle.
Next, if you get the number, all 158 digits, and you want to add them using your strategy, you may need to convert the strings you get (a substring is a string, after all) to a Number.
But really, the question is, can you determine the sum of the digits without calculating the number?

Related

javascript loops give different results

This is probably a question with an really logical answer.. But I really don't understand this!!
Why, does this give different results..
Only difference is a for loop and a while loop.. Even while they loop exactly as many times???
array = [1.2344, 2.47373, 3.444];
var total = 0,
total2 = 0,
i = array.length,
whileLoops = 0,
forLoops = 0;
while (i--) {
whileLoops++;
total += array[i];
}
for (var i = 0, len = array.length; i < len; i++) {
forLoops++;
total2 += array[i];
}
if (total !== total2) {
console.log("BOE")
}
I tried parseFloat, but this also wasn't helping :(
It it because the Javascript engine rounds numbers in a sort of way???
On request: the fiddle http://jsfiddle.net/5dsx0ump/
UPDATE
Would the solution be to first to a * 1000 and after all the calculations, divide again by 1000, to keep round numbers?
The difference in the loops is the order that you add the numbers.
For each of those additions there is a tiny loss of data, as the result has to fit in the same data type as both the operands. What's lost depends on what the numbers are, so adding the numbers in different order causes a small difference in the result in the end.
If you print out the numbers, they may or may not look the same, but looking the same when printed doesn't mean that they must have the same value. The numbers have a precision of 15-17 digits, but that is rounded to slightly less when printed, just to avoid seeing the limitation in precision.
This is normal behaviour for floating point numbers, and you would see the same result in any programming language using floating point numbers. Floating point numbers are simply not exact, so in application where numbers actually have to be exact (e.g. banking), other data types are used.
Floating-point math (in JavaScript or any other language) has some quirks that you wouldn't expect. Putting this at the end of your code:
console.log(total, total2);
Returns the following:
7.1521300000000005 7.15213
Heck, just put 0.1 + 0.2 in a browser console and see what you get. Not what you'd expect.
Instead of re-hashing the entire explanation, there's a really good write-up and discussion here: Is floating point math broken?

toFixed(2) function not working

This one is weird, because I got it running in this fiddle but it is not working in the main fiddle. I believe the code is the same.
Here is the main function:
window.setInterval(function(){
for(var i=0; i < companies.length; i++) {
var randomVal = (Math.random()*(10 - (-10) + 1)) + (-10);
randomVal = randomVal / 100;
randomVal = Number(randomVal.toFixed(2));
companies[i].price += randomVal;
//companies[i].price = companies[i].price.toFixed(2);
$('#price'+i).html(companies[i].price);
}
}, 1000);
A value like 34.569999999999986 isnt been cut down to 34.56.
Any idea what is wrong?
This has to do with a common problem that occurs when converting between binary floating point values and decimal representations. See this fiddle, which is like your "working" one, but I altered the price value so that it also breaks.
Here's an even simpler demo that gets right to the heart of the problem: http://jsfiddle.net/2NHSM/4/
As you can see, the output of 1.23 - 1 is 0.22999999999999998. That's obviously off by a little bit, but it has to do with the way computers represent numbers.
Computers hold numbers as binary digits. 1.23 is actually a "repeating decimal" in binary (just like 1/7 is repeating in decimal), so there's no 100% accurate way to store it. As a result, when you subtract 1.23 - 1 you get an answer that is slightly off because 1.23 was never accurate to begin with.
The same thing is happening in your case. To fix it, just use toFixed right before you display the value, not before you add something else to it.
Update
Here's a working fiddle: http://jsfiddle.net/2NHSM/6/
Update 2
Also note that toFixed can have unexpected rounding behavior. Try the following in the console:
1.35.toFixed(1);
// => 1.4
1.45.toFixed(1);
// => 1.4
You might want to use Math.round instead.
Math.round(1.35 * 10) / 10
// => 1.4
Math.round(1.45 * 10) / 10
// => 1.5
Floating points are approximations so when you add, they don't always end up clean numbers. Just call toFixed when you display it:
companies[i].price += randomVal;
$('#price'+i).html(companies[i].price.toFixed(2));
Demo
This is why your //companies[i].price = companies[i].price.toFixed(2); didn't work:
toFixed() returns a string, so after the first call, companies[i].price is a string. When you do companies[i].price += randomVal;, it is doing string concatenation instead of numeric addition. It'll produce something like:
577.05
577.050.05
577.050.050.1
So you can't call toFixed on it anymore because:
It's a string
It's not even a valid number
So, how would you fix that? Convert it to a number by multiplying by 1 (or Number());
companies[i].price += randomVal;
companies[i].price = companies[i].price.toFixed(2)*1;
$('#price'+i).html(companies[i].price);
Demo
With either of these solutions, the first call to toFixed() is unnecessary.
That's because after applying .toFixed() you're adding the value to another variable, which then causes the precision to go haywire again.
Instead use this for displaying:
$('#price'+i).html(companies[i].price.toFixed(2));
The reason it works in your first example is because you are resetting the value of price to 577 on each pass.
Try this, it calls .toFixed(2) on the price after the sum has been calculated and also returns it back to your variable.
You can probably ditch the first .toFixed thats called on randomVal.
window.setInterval(function(){
for(var i=0; i < companies.length; i++) {
var randomVal = (Math.random()*(10 - (-10) + 1)) + (-10);
randomVal = randomVal / 100;
randomVal = Number(randomVal.toFixed(2));
companies[i].price += randomVal;
companies[i].price = Number(companies[i].price.toFixed(2));
$('#price'+i).html(companies[i].price);
}
}, 1000);
your conversion data is response[25] and follow the below steps.
var i = parseFloat(response[25]).toFixed(2)
console.log(i)//-6527.34

Chunk a string every odd and even position

I know nothing about javascript.
Assuming the string "3005600008000", I need to find a way to multiply all the digits in the odd numbered positions by 2 and the digits in the even numbered positions by 1.
This pseudo code I wrote outputs (I think) TRUE for the odd numbers (i.e. "0"),
var camid;
var LN= camid.length;
var mychar = camid.charAt(LN%2);
var arr = new Array(camid);
for(var i=0; i<arr.length; i++) {
var value = arr[i]%2;
Alert(i =" "+value);
}
I am not sure this is right: I don't believe it's chunking/splitting the string at odd (And later even) positions.
How do I that? Can you please provide some hints?
/=================================================/
My goal is to implement in a web page a validation routine for a smartcard id number.
The logic I am trying to implement is as follows:
· 1) Starting from the left, multiply all the digits in the odd numbered positions by 2 and the digits in the even numbered positions by 1.
· 2) If the result of a multiplication of a single digit by 2 results in a two-digit number (say "7 x 2 = 14"), add the digits of the result together to produce a new single-digit result ("1+4=5").
· 3) Add all single-digit results together.
· 4) The check digit is the amount you must add to this result in order to reach the next highest multiple of ten. For instance, if the sum in step #3 is 22, to reach the next highest multiple of 10 (which is 30) you must add 8 to 22. Thus the check digit is 8.
That is the whole idea. Google searches on smartcard id validation returned nothing and I am beginning to think this is overkill to do this in Javascript...
Any input welcome.
var theArray = camid.split(''); // create an array entry for each digit in camid
var size = theArray.length, i, eachValue;
for(i = 0; i < size; i++) { // iterate over each digit
eachValue = parseInt(theArray[i], 10); // test each string digit for an integer
if(!isNaN(eachValue)) {
alert((eachValue % 2) ? eachValue * 2 : eachValue); // if mod outputs 1 / true (due to odd number) multiply the value by 2. If mod outputs 0 / false output value
}
}
I discovered that what I am trying to do is called a Luhn validation.
I found an algorithm right here.
http://sites.google.com/site/abapexamples/javascript/luhn-validation
Thanks for taking the time to help me out. Much appreciated.
It looks like you might be building to a Luhn validation. If so, notice that you need to count odd/even from the RIGHT not the left of the string.

How to make 5509.099999999999 as 5509.09 using javascript

How to make 5509.099999999999 as 5509.09 using javascript.
Lots of mathy options that end up with .1 so how about;
var f = 5509.099999999999
if ((f = f.toString()).indexOf(".") >= 0)
f = f.substr(0, 3 + f.indexOf("."))
print(parseFloat(f))
>>5509.09
Have you tried this?
var value = 5509.099999999999;
var str = value.toString();
var result = str.substr(0,7);
Then if you need it to be a float again you can do:
var FinalAnswer = parseFloat(result);
You don't need all these variables, but that is the step by step.
var result = (Math.round((5509.09999 * 100) - 1)) / 100;
You could use .toFixed(2) but this will round the value, so in your example you'll end up with 5509.10 instead of 5509.09.
The next best option is to use Math.floor(), which truncates rather than rounding. Unfortunately, this only gives integer results, so to get the result to 2 decimal places, you'd need to multiply by 100, then use Math.floor(), and then divide by 100 again.
var value = 5509.099999999999;
var result = Math.floor(value*100)/100;
[EDIT]
Hmm, unfortunately, the above doesn't work due to problems with floating point precision -- even just the first step of multiplying it by 100 gives 550910.
Which means that the best answer is likely to be converting it to a string and chopping the string into bits.
var value = 5509.099999999999;
var str_value = value.toString();
var bits = str_value.split('.');
var result = bits[0]+"."+bits[1].substr(0,2);
I wouldn't normally suggest doing string manipulation for this sort of thing, because it is obviously a maths problem, but given the specific requirements of the question, it does seem that this is the only workable solution in this case.
You can truncate the number to a certain number of decimal places using this function:
function truncateNumber(number, digits){
var divisor = Math.pow(10,digits);
return Math.floor(number*divisor)/divisor;
}
If you want to round the number instead, you can use JavaScript's built in Number.toFixed function. If you always want the number a certain number of digits long, you can use the Number.toPrecision function.
if you want to take two decimal places, you can use .toPrecision(n) javascript function, where n is the total number of digits desired.
so, for your example, you'd have to do
var x = 5509.099999999999;
x = x.toPrecision(6);
this, however, rounds results in 5509.10

Unlimited-size base conversion?

I'm trying to implement a BigInt type in JavaScript using an array of integers. For now each one has an upper-bound of 256. I've finished implementing all integer operations, but I can't figure out how to convert the BigInt to its string representation. Of course, the simple way is this:
BigInt.prototype.toString = function(base) {
var s = '', total = 0, i, conv = [
,,
'01',
'012',
'0123',
'01234',
'012345',
'0123456',
'01234567',
'012345678',
'0123456789',
,
,
,
,
,
'0123456789abcdef'
];
base = base || 10;
for(i = this.bytes.length - 1; i >= 0; i--) {
total += this.bytes[i] * Math.pow(BigInt.ByteMax, this.bytes.length - 1 - i);
}
while(total) {
s = conv[base].charAt(total % base) + s;
total = Math.floor(total / base);
}
return s || '0';
};
But when the BigInts actually get big, I won't be able to convert by adding anymore. How can I convert an array of base-x to an array of base-y?
See the example I gave in this answer to a similar question recently (it's for base-10 to base-3, but the principle should be transferrable): C Fast base convert from decimal to ternary.
In summary:
Iterate over the input
digits, from low to high. For each
digit position, first calculate what
1000....000 (base-256) would be in the output representation (it's 256x the previous
power of 256). Then multiply that
result by the digit, and accumulate
into the output representation.
You will need routines that perform
multiplication and addition in the
output representation. The
multiplication routine can be written
in terms of the addition routine.
Note that I make no claims that this approach is in any way fast (I think it's O(n^2) in the number of digits); I'm sure there are algorithmically faster approaches than this.
If you're prepared to put on your math thinking cap more than I am right now, someone seems to have explained how to convert digit representations using Pascal's triangle:
http://home.ccil.org/~remlaps/DispConWeb/index.html
There are links to the source code near the bottom. They're in Java rather than JavaScript, but if you're putting in the effort to grok the math, you can probably come up with your own implementation or put in the effort to port the code...

Categories

Resources