Pow and mod function optimization - javascript

I need to create an optimized function to count Math.pow(a,b) % c; in Javascript;
There's no problems while counting small numbers like: Math.pow(2345,123) % 1234567;
But if you try to count: Math.pow(2345678910, 123456789) % 1234567; you'll get incorrect result because of Math.pow() function result that cannot count up "big" numbers;
My solution was:
function powMod(base, pow, mod){
var i, result = 1;
for ( i = 0; i < pow; i++){
result *= base;
result %= mod;
}
return result;
Though it needs a lot of time to be counted;
Is it possible to optimized it somehow or find more rational way to count up Math.pow(a, b) % c; for "big" numbers? (I wrote "big" because they are not really bigIntegers);

Based on SICP.
function expmod( base, exp, mod ){
if (exp == 0) return 1;
if (exp % 2 == 0){
return Math.pow( expmod( base, (exp / 2), mod), 2) % mod;
}
else {
return (base * expmod( base, (exp - 1), mod)) % mod;
}
}
This one should be quicker than first powering and then taking remainder, as it takes remainder every time you multiply, thus making actual numbers stay relatively small.

Your method is good so far, but you will want to do http://en.wikipedia.org/wiki/Exponentiation_by_squaring also known as http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method
The idea is that x^45 is the same as (expanded into binary) x^(32+8+4+1), which is the same as x^32 * x^8 * x^4 * x^1
And you first calculate x^1, then x^2 == (x^1)^2, then x^4 == (x^2)^2, then x^8 == (x^4)^2, then...

you can also use the mountgomery reduction in combination with exponentiation which is largely useful for large exponents > 256:
http://en.wikipedia.org/wiki/Montgomery_reduction#Modular_exponentiation
It has also been implemented in this BigInteger Library for RSA-encryption:
http://www-cs-students.stanford.edu/~tjw/jsbn/

Related

How to find power of 11 or x is power n in javascript?

I am trying to find 11 power of n. I know in JavaScript there is a function Math.pow which give you power of number.I want to implement that function by own.my function is working perfectly , but its time complexity is O(n) can we reduce that time complexity using any other method?
I am thinking to use bit map, but not getting success.
function power(x,n) {
let sum =1
for(let i =0;i<n;i++){
sum*=x
}
return sum
}
console.log(power(11,3))
You could take the proposed square approach.
The complexity is O(log2(n)), like this table with the counts of the function.
n counts
------- ------
100 7
1000 10
10000 14
100000 17
function power(x, n) {
if (n === 1) return x;
let temp = power(x, n >> 1);
return n % 2
? x * temp * temp
: temp * temp;
}
console.log(power(11, 3)); // 1331 with 2 calls
One possible approach:
function power(x, n) {
let res = 1;
let acc = x;
while (n > 0) {
if (n & 1) res *= acc;
acc *= acc;
n >>= 1;
}
return res;
}
console.log(power(11, 0)); // 1
console.log(power(11, 1)); // 11
console.log(power(11, 2)); // 121
console.log(power(11, 3)); // 1331
console.log(power(11, 5)); // 161051
console.log(power(11, 8)); // 214358881 etc.
The idea is memoizing the results of subsequent squaring of the original number (x). At each step n is halved, so it's O(log n) instead of O(n). It's quite similar to #NinaScholz solution, but is iterative, not recursive (which I actually consider a benefit).
(and yes, in any real world app there should definitely be a check for MAX_SAFE_INTEGER as well, but I suppose we're discussing an algorithm here)
Here is a straightforward JS implementation of the squre approach:
function exp_by_squaring(x,n){
if(n < 0)
return exp_by_squaring(1 / x, -n);
else if(n === 0)
return 1;
else if(n === 1)
return x ;
else if(n %2===0)
return exp_by_squaring(x * x, n / 2);
else
return x * exp_by_squaring(x * x, (n - 1) / 2);
}
I also created a benchmark with some of the approaches from other answers, have a look:
Benchmark
This appears quicker than your original implementation, although not elegant
function power(x,n){
return Array.apply(null,Array(n)).reduce((r,v) => r*x, 1)
}
I am not yet able to just comment on your question but I hope I understand your question good enough. Is this something you are looking for?
const myPow = (x, y) => x ** y;

Confusion about the behavior between arithmetic operators and functions?

function pow(x, n) {
if (n == 1) {
return x;
} else {
return x * pow(x, n - 1);
}
}
alert( pow(2, 3) ); // 8
source = https://javascript.info/recursion
Hello all! I'm confused about the second return statement of this function:
return x * pow(x, n - 1);
I'm just looking for either some clarification or a reference to that behavior.
From my perspective, it looks like x is multiplied only by the first parameter of the function, and the n-1 is ignored.
(How does n-1 affect the result <- original question)
Sorry, I messed up the original question...
I want to ask how does javascript interprets that multiplication. When multiplying an integer and a function, I don't quite understand what's happening. How does javascript choose what to multiply with more than one parameter?
pow(2, 3) = 2 * pow(2, 2) = 2 * 2 * pow(2, 1) = 2 * 2 * 2
You are not actually calculating a product with n - 1, but refer to n as a counter. This is equivalent to
var result = 1;
while (n >= 0) {
result *= x;
n--;
}

Do you know of a computer algorithm to solve the ability to divide without division operators?

Through applying a computer science algorithm in JavaScript, could you solve the following question?
The function accepts a numerator and denominator in the form of a positive or negative integer value.
You can not use '*', '/' or '%'.
function divide(num, denom) {
// ...
}
divide(6, 2)
divide(-10, 5)
divide(7, 2)
divide(-5, 10)
I am curious to know if there is a known computer science algorithm out there that can solve this.
I saw this question and had to take a crack at it, I've implemented a solution that can get decimal places up to a specified precision as well as handle negatives, it uses a recursive approach and some string manipulation.
// Calculate up to decimal point
const MAX_PRECISION = 6;
function divide(numerator, denominator, answer=0, decimals=MAX_PRECISION)
{
// Account for negative numbers
if ((numerator < 0 || denominator < 0))
{
// If both are negative, then we return a positive, otherwise return a negative
if (numerator < 0 && denominator < 0)
return divide(Math.abs(numerator), Math.abs(denominator))
else return -divide(Math.abs(numerator), Math.abs(denominator));
}
// Base case return if evenly divisble or we've reached the specificed percision
if (numerator == 0 || decimals == 0) return answer;
// Calculate the decimal places
if (numerator < denominator)
{
// Move the decinal place to the right
const timesTen = parseInt(numerator + "0");
// Calcualte decimal places up to the certain percision
if (decimals == MAX_PRECISION)
return parseFloat(answer + "." + divide(timesTen, denominator, 0, decimals-1));
else return answer + "" + divide(timesTen, denominator, 0, decimals-1);
}
// Perform the calculations in a tail-recursive manor
return divide(numerator-denominator, denominator, answer+1, decimals);
}
// Test Cases
console.log(divide(10, 2));
console.log(divide(10, -2));
console.log(divide(-7, -4));
console.log(divide( 1, -2));
console.log(divide(11, 3));
console.log(divide(22, 7));
You can try Something like:
function divide(num, denom) {
var count = 0;
while (num > 0) {
num = num - denom
if (num >= 0) {
count ++;
}
}
return count;
}

Getting a remainder without the modulo (%) operator in Javascript, accounting for -/+ sign

For a homework assignment, I need to return the remainder after dividing num1 by num2 WITHOUT using the built-in modulo (%) operator. I'm able to get most tests to pass with the following code, but I'm stuck on how to account for -/+ signs of the given numbers. I need to carry over whichever sign is on num1, and also return a positive number if the num2 is negative - it's blowing my mind how to do this... :) Any clarity would be greatly appreciated! I'm not exactly looking for the straight up answer here, more that I seem to be missing something obvious... Maybe I need a new approach?
function modulo(num1, num2) {
if (num1 === 0) {
return 0;
}
if (num2 === 0 || isNaN(num1) || isNaN(num2)) {
return NaN;
}
if (num1 < num2) {
return num1;
}
if (num1 > 0 && num2 > 0) {
var counter = num1;
while (counter >= Math.abs(num2)) {
counter = counter - num2;
}
return counter;
}
}
var output = modulo(25, 4);
console.log(output); // 1
If you think about the mathematical process to calculate modulus you might be able see how you can do this without having to resort to a bunch of case statements. Instead think of it this way, you're just calculating a remainder:
Given 2 numbers a and b, you can compute mod(a,b) by doing the following:
q = a / b; //finding quotient (integer part only)
p = q * b; //finding product
remainder = a - p; //finding modulus
Using this idea, you should be able to transfer it to JS. You said you're not looking for the straight up answer so that's all I'll say!
Edit: here is the code, like I said in the comments it's exactly the pseudocode I posted above:
function modulo(a,b){
q = parseInt(a / b); //finding quotient (integer part only)
p = q * b; //finding product
return a - p; //finding modulus
}
This will return the exact same values as using %
You might be overthinking this. You basically stated the solution in your question:
I need to carry over whichever sign is on num1, and also return a positive number if the num2 is negative
The second part isn't accurate, but I suspect you just misspoke. A positive number should be returned when num2 is negative unless num1 is negative.
At any rate, the important takeaway is that if num1 is negative the result will be negative, and otherwise the result will be positive. The sign of num2 is discarded.
Starting the code you've written (which others will be quick to point out isn't the simplest solution), the fix is to compute the remainder using both numbers' absolute values, and then apply num1's original sign to the result.
function modulo(num1, num2) {
var sign = num1 < 0 ? -1 : 1;
var dividend = Math.abs(num1);
var divisor = Math.abs(num2);
if (dividend === 0) {
return 0;
}
if (dividend === 0 || isNaN(dividend) || isNaN(divisor)) {
return NaN;
}
if (dividend < divisor) {
return sign * dividend;
}
var counter = dividend;
while (counter >= divisor) {
counter = counter - divisor;
}
return sign * counter;
}
console.log( 25 % 4, modulo( 25, 4));
console.log(-25 % 4, modulo(-25, 4));
console.log( 25 % -4, modulo( 25, -4));
console.log(-25 % -4, modulo(-25, -4));
.as-console-wrapper{min-height:100%;}
This is the basic formula:
dividend = divisor * quotient + remainder
From this equation you can calculate the remainder.

How to convert the last 3 digits of the number?

How to convert the last 3 digits of the number? Numbers will be bigger then 8000.
For example:
From 249439 to 249000?
You can get the last three digits using the modulus operator %, which (for positive numbers) computes the remainder after integer division; for example, 249439 % 1000 is 439.
So to round down to the nearest thousand, you can just subtract those three digits:
var rounded = original - original % 1000;
(for example, if original is 249439, then rounded will be 249000).
I'd suggest the following:
function roundLastNDigits (num, digits) {
// making sure the variables exist, and are numbers; if *not* we quit at this point:
if (!num || !parseInt(num,10) || !digits || !parseInt(digits,10)) {
return false;
}
else {
/* otherwise we:
- divide the number by 10 raised to the number of digits
(to shift divide the number so that those digits follow
the decimal point), then
- we round that number, then
- multiply by ten raised to the number of digits (to
recreate the same 'size' number/restoring the decimal fraction
to an integer 'portion' */
return Math.round(num / Math.pow(10, parseInt(digits,10))) * Math.pow(10,digits);
}
}
console.log(roundLastNDigits(249439, 3))
JS Fiddle demo.
If you'd prefer to always round down, I'd amend the above to give:
function roundLastNDigits (num, digits) {
if (!num || !parseInt(num,10) || !digits || !parseInt(digits,10)) {
return false;
}
else {
return Math.floor(num / Math.pow(10, parseInt(digits,10))) * Math.pow(10,digits);
}
}
console.log(roundLastNDigits(8501, 3))
JS Fiddle demo.
Simplifying the above by incorporating ruakh's genius approach:
function roundLastNDigits (num, digits) {
if (!num || !parseInt(num,10) || !digits || !parseInt(digits,10)) {
return false;
}
else {
return num - (num % Math.pow(10,parseInt(digits,10)));
}
}
console.log(roundLastNDigits(8501, 3))
JS Fiddle demo.
Or, finally, given that you only need to replace the last three digit characters with 0:
function roundLastNDigits (num, digits) {
if (!num || !digits || !parseInt(digits,10)) {
return false;
}
else {
var reg = new RegExp('\\d{' + digits + '}$');
return num.toString().replace(reg, function (a) {
return new Array(parseInt(digits,10) + 1).join(0);
});
}
}
console.log(roundLastNDigits(8501, 3))
JS Fiddle demo.
References:
Math.floor().
Math.pow().
Math.round().
parseInt().
For always rounding down I'd suggest dividing out 1000, casting to Int then multipling back in 1000
var x = 249439,
y = ((x / 1000) | 0) * 1000; // 249000
1)
Math.round(num.toPrecision(3));
This doesn't account for the values before the 3rd value to round.
2)
This is sort of a bad solution but it works.
num = 50343 // whatever your input is.
m = 10^n.
Math.round(num*m)/m
n being the amount you want to move over.

Categories

Resources