function to multiply (and saturate) 2 int32_t arguments - multiplication

I need to write a function, which multiplies and saturates 2 arguments (int32_t) and returns also int32_t. Everything inside must be counted within limits of int32_t. If multiplying under/overflows int32_t the result muse be saturated by INT32MAX and INT32MIN.
my solution is following: but it has
int32_t multiple_or_saturate(int32_t a, int32_t b)
{
if(((a >= 0) && (b >= 0)) || ((a < 0) && (b < 0)))
{
if((INT32_MAX / a) >= b)
{
return(a * b);
}
else
{
return(INT32_MAX);
}
}
else
{
if((INT32_MIN / a ) <= b)
{
return(a * b);
}
else
{
return(INT32_MIN);
}
}
}

I would say that the division is quite expensive here. It would be more efficient to store the result of the multiplication in a 64 bit variable, then check the result and then saturate it if needed.
Some compilers also support the usage of MMX intrinsics for saturating arithmetic. There are most probably an assembler instruction for it (depending on hardware of course), you just need to use a compiler that knows haw to use it.

Related

Why is the time-complexity for modulus operation constant?

I am working through Cracking the Coding Interview, and I am unsure of an example on time-complexity. They provide this code to determine if a number is prime:
boolean isPrime(int n) {
for (int x = 2; x * x <= n; x++) {
if (n % x == 0) {
return false;
}
}
return true;
}
Later they say "The work inside the for loop is constant". Why is run-time for modulus operator constant? Why does it not depend on n?
The key part of the statement there is inside the for loop. All that's happening is a a modulo operation. Inside the function itself the time complexity depends on n

java method: java.lang.Integer.numberOfLeadingZeros(int) can be optimized

the origin code is :
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
I think it can be optimized ,should add following condition:
if (i < 0)
return 0;
the fully optimized code is :
public static int numberOfLeadingZeros(int i) {
if(i<=0) {
return i < 0 ? 0 : 32;
}
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
In theory yes, your suggestion makes sense.
In practice, unless you use an exotic JVM, it will not make any difference because the method is intrinsic, so the code that is executed is not the code you can find in the Java class.
For example on x86/64 cpus, the code is here and uses the bsrl CPU instruction, which is as fast as you can hope for.
Besides the fact that this method will likely get replaced by an intrinsic operation for hot spots, this check for negative numbers is only an improvement, if the number is negative. For positive numbers, it is just an additional condition to be evaluated.
So the worth of this optimization depends on the likelihood of negative arguments at this function. When I consider typical use cases of this function, I’d consider negative values a corner case rather than typical argument.
Note that the special handling of zero at the beginning is not an optimization, but a requirement as the algorithm wouldn’t return the correct result for zero without that special handling.
Since your bug report yield to finding an alternative (also shown in your updated question) which improves the negative number case without affecting the performance of the positive number case, as it fuses the required zero test and the test for negative numbers into a single pre-test, there is nothing preventing the suggested optimization.
Bug has been created on oracle bug database: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8189230

how much time will fibonacci series will take to compute?

i have created the recursive call tree by applying brute force technique but when i give this algorithm 100 values it takes trillion of years to compute..
what you guys suggest me to do that it runs fast by giving 100 values
here is what i have done so far
function fib(n) {
if (n =< 1) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
You can do it also with a loop:
int a = 1;
int b = 1;
for(int i = 2; i < 100; i++){
int temp = a + b;
a = b;
b = temp;
}
System.out.println("Fib 100 is: "+b);
The runtime is linear and avoids the overhead caused by the recursive calls.
EDIT: Please note that the result is wrong. Since Fib(100) is bigger than Integer.MAX_VALUE you have to use BigInteger or similar to get the correct output but the "logic" will stay the same.
You could have a "cache", where you save already computed Fibonacci numbers. Every time you try to compute
fib(n-1) /* or */ fib(n-2) ;
You would first look into your array of already computed numbers. If it's there, you save a whole lot of time.
So every time you do compute a fibonacci number, save it into your array or list, at the corresponding index.
function fib(n)
{
if (n =< 1)
{
return n;
}
if(fiboList[n] != defaultValue)
{
return fiboList[n];
}
else
{
int fibo = fib(n-1) + fib(n-2);
fiboList[n] = fibo;
return fibo;
}
}
You can also do it by dynamic programming:
def fibo(n):
dp = [0,1] + ([0]*n)
def dpfib(n):
return dp[n-1] + dp[n-2]
for i in range(2,n+2):
dp[i] = dpfib(i)
return dp[n]

What is the Modulo function for negative decimals Objective-C?

I need to calculate modulos with decimals that can be negative as well
for example: fmod( -5.2, 3 );
while mod() works with integers, and fmod() (or fmodf()) works well with decimals, fmod() returns wrong results with negative decimals:
ex:
double modulo = fmod (5.2, 3);
NSLog (#"==> %f", modulo);
==> 2.2 // This is correct !!
double modulo = fmod (-5.2, 3);
NSLog (#"==> %f", modulo);
==> -2.2 // This is wrong !! should be 0.8
Is there another mod() in the library or should i write my own decimal negative mod function ?
something like :
if (res = fmod(x,m) < 0) {
res+=m;
}
Thx !
-2.2 is correct and is also -5.2 mod 3. The fmod function is a C function (and therefore also Objective C), so you can find more detail about it by typing man fmod into terminal. When doing fmod it will preserve the sign of the value that you are moding. So to get the mod you want, you will need to check the sign (of either the result, or the value you are passing in) and if it is negative you will need to add the modulo base, in this case 3.
This is the definition of the fmod function:
double
fmod(double x, double y);
Specifically, the functions return the value x-i*y, for some integer i such that, if y is non-zero, the result has the same sign as x and magnitude less than the magnitude of y.
from the OS X man page.
For your purposes, you can do something like this:
#include <math.h>
float f_mod(float a, float n) {
return a - n * floor(a / n);
}
Of course, be careful to check n>0.
f_mod(-5.2f, 2.0f) = 0.8
f_mod(5.2f, 2.0f) = 2.2
Thank you so i ended up writing a wrapper... What i was hopping i could avoid. This works great for me, and, in my opinion, represents the correct mathematical definition of the modulo (not the C implementation). I am sure this function can be optimized,but for clarity i leave it this way:
//--
//-- Modulo
//--
double calcModulo ( double x, double m) {
double res = INFINITY;
if (m==0)
return res ;
double posMod, negMod, posM, posX;
posM = m < 0 ? -m:m;
posX = x < 0 ? -x:x;
posMod = fmod (posX, posM);
negMod = fmod (-posX,posM) + posM;
// pick up the correct res
if ( x >= 0 ){
if (m > 0) {
res = posMod;
} else {
res = -negMod;
}
}else{
if (m > 0) {
res= negMod;
} else{
res= -posMod;
}
}
return res;
}

Rounding with significant digits

In Xcode /Objective-C for the iPhone.
I have a float with the value 0.00004876544. How would I get it to display to two decimal places after the first significant number?
For example, 0.00004876544 would read 0.000049.
I didn't run this through a compiler to double-check it, but here's the basic jist of the algorithm (converted from the answer to this question):
-(float) round:(float)num toSignificantFigures:(int)n {
if(num == 0) {
return 0;
}
double d = ceil(log10(num < 0 ? -num: num));
int power = n - (int) d;
double magnitude = pow(10, power);
long shifted = round(num*magnitude);
return shifted/magnitude;
}
The important thing to remember is that Objective-C is a superset of C, so anything that is valid in C is also valid in Objective-C. This method uses C functions defined in math.h.