How can I do multiply two numbers without the '*' or '/' operator
It's different from the other question because I need float too
I need to consider negative with positive, real with fraction, every possibility of multiply
I have an Idea that I will do the real number first (5, 3, 8 and etc...) and then the fraction(0.5, 0.33333, and etc...)
float fraction = (float)x - (int)x; // I can calculate the fraction with this
I think I can "multiply" the fraction to be int and then do the multiply with real numbers but the problem is how I return it back how it was (divide by ten without divide)
With this (do this function until the number return is bigger then 0):
float multiBy10(float a)
{
float backup = a;
for(int i = 0; i < 10; i++, a += backup);
return a;
}
I saw this here but it with int and bit manipulation don't work on float number
int divs10(int n)
{
int q, r;
n = n + (n>>31 & 9);
q = (n >> 1) + (n >> 2);
q = q + (q >> 4);
q = q + (q >> 8);
q = q + (q >> 16);
q = q >> 3;
r = n - q*10;
return q + ((r + 6) >> 4);
// return q + (r > 9);
}
Related
I need to write a program that takes 2 digits(X and n) and then prints X with last n digits of X reversed.
For example
Input: 12345 3
Output: 12543
Input: 523 2
Output: 532
I already wrote a control mechanism for checking n is greater or equal than the number of digits of X
For example if inputs are 6343 and 7, program prints that inputs should be changed and takes input again.
My main problem is I couldn't find an algorithm for reversing last n digits. I can reverse any int with this code
int X, r = 0;
printf("Enter a number to reverse\n");
scanf("%d", &n);
while (X != 0)
{
r = r * 10;
r = r + n%10;
X = X/10;
}
printf("Reverse of the number = %d", r);
But I couldn't figure how two reverse just last digits. Can you give me any idea for that?
I couldn't figure how to reverse just last digits
Separate the number using pow(10,n) - see later code.
unsigned reverse_last_digits(unsigned x, unsigned n) {
unsigned pow10 = powu(10, n);
unsigned lower = x%pow10;
unsigned upper = x - lower;
return upper + reverseu(lower, n);
}
Create a loop that extracts the least-significant-digit (%10) and builds up another integer by applying that digit. (y = y*10 + new_digit)
unsigned reverseu(unsigned x, unsigned n) {
unsigned y = 0;
while (n-- > 0) {
y = y*10 + x%10;
x /= 10;
}
return y;
}
For integer type problems, consider integer helper functions and avoid floating point functions like pow() as they may provide only an approximate results. Easy enough to code an integer pow().
unsigned powu(unsigned x, unsigned expo) {
unsigned y = 1;
while (expo > 0) {
if (expo & 1) {
y = x * y;
}
expo >>= 1;
x *= x;
}
return y;
}
Test
int main() {
printf("%u\n", reverse_last_digits(12345, 3));
printf("%u\n", reverse_last_digits(523, 2));
printf("%u\n", reverse_last_digits(42001, 3));
printf("%u\n", reverse_last_digits(1, 2));
}
Output
12543
532
42100
10
Code uses unsigned rather than int to avoid undefined behavior (UB) on int overflow.
It is an easy one.
1. let say the number you want to reverse is curr_number;
2. Now, the places you want to reverse is x;
(remember to verify that x must be less than the number of digit of curr_number);
3. now, just take a temp integer and store curr_number / pow(10,x) ('/' = divide and pow(10,x) is 10 to the power x)
4. now, take a second number temp2, which will store curr_number-(temp * pow(10,x) )
5. reverse this temp2 (using your function)
6. now, answer = (temp * pow(10,x) ) + (temp2) //(note temp2 is reversed)
example with steps:
curr_number = 1234567
places you want to reverse is 3
temp = 1234567 / (10^3) i.e (1234567/1000) = 1234 (because it is int type)
temp2 = 1234567 - (1234*10^3) i.e 1234567 - 1234000 = 567
reverse(567) = 765
answer = (1234 * 10^3) + 765 = 1234765
Create two variables
lastn which stores the last n digits (345)
r which stores the reversed last n digits (543)
Subtract lastn from the original number (12345 - 345 = 12000)
Add r to the above number (12000 + 543 = 12543)
int c = 0; // count number of digits
int original = x;
int lastn = 0;
while (x != 0 && c < n) {
r = r * 10;
r = r + x % 10;
lastn += (x % 10) * pow(10, c);
x = x / 10;
c++;
}
printf("reversed: %d\n", original - lastn + r);
In case you don't have problems using char, you can do this
#include <stdio.h>
#include <string.h>
#define SIZE 10
int main() {
char n[SIZE]; // the Number;
int x; // number of last digits of n to reverse
int len; // number of digits of n
scanf("%s%d", n, &x);
len = strlen(n);
for(int i = 0; i < len; i++) {
i < len - x ? printf("%c", n[i]) : printf("%c", n[2*len -1 - i - x]);
}
return 0;
}
If you want you can make the program more readable by splitting the for in two
for(int i = 0; i < len - x; i++) {
printf("%c", n[i]);
}
for(int i = len-1; i >= len - x; i--) {
printf("%c", n[i]);
}
Note: the program won't work if n > x (i.e. if you want to swap more digits than you got)
I try two function for modular exponentiation for big base return wrong results,
One of the function is:
uint64_t modular_exponentiation(uint64_t x, uint64_t y, uint64_t p)
{
uint64_t res = 1; // Initialize result
x = x % p; // Update x if it is more than or
// equal to p
while (y > 0)
{
// If y is odd, multiply x with result
if (y & 1)
res = (res*x) % p;
// y must be even now
y = y>>1; // y = y/2
x = (x*x) % p;
}
return res;
}
For input x = 1103362698 ,y = 137911680 , p=1217409241131113809;
It return the value (x^y mod p):749298230523009574(Incorrect).
The correct value is:152166603192600961
The other function i try, gave same result, What is wrong with these functions?
The other one is :
long int exponentMod(long int A, long int B, long int C)
{
// Base cases
if (A == 0)
return 0;
if (B == 0)
return 1;
// If B is even
long int y;
if (B % 2 == 0) {
y = exponentMod(A, B / 2, C);
y = (y * y) % C;
}
// If B is odd
else {
y = A % C;
y = (y * exponentMod(A, B - 1, C) % C) % C;
}
return (long int)((y + C) % C);
}
With p = 1217409241131113809, this value as well as any intermediate values for res and x will be larger than 32 bits. This means that multiplying two of these numbers could result in a value larger than 64 bits which overflows the datatype you're using.
If you restrict the parameters to 32 bit datatypes and use 64 bit datatypes for intermediate values then the function will work. Otherwise you'll need to use a big number library to get correct output.
I need to compute the mathematical expression floor(ln(u)/ln(1-p)) for 0 < u < 1 and 0 < p < 1 in C on an embedded processor with no floating point arithmetics and no ln function. The result is a positive integer. I know about the limit cases (p=0), I'll deal with them later...
I imagine that the solution involves having u and p range over 0..UINT16_MAX, and appeal to a lookup table for the logarithm, but I cannot figure out how exactly: what does the lookup table map to?
The result needs not be 100% exact, approximations are OK.
Thanks!
Since the logarithm is used in both dividend and divisor, there is no need to use log(); we can use log2() instead. Due to the restrictions on the inputs u and p the logarithms are known to be both negative, so we can restrict ourselves to compute the positive quantity -log2().
We can use fixed-point arithmetic to compute the logarithm. We do so by multiplying the original input by a sequence of factors of decreasing magnitude that approach 1. Considering each of the factor in sequence, we multiply the input only by those factors that result in a product closer to 1, but without exceeding it. While doing so, we sum the log2() of the factors that "fit". At the end of this procedure we wind up with a number very close to 1 as our final product, and a sum that represents the binary logarithm.
This process is known in the literature as multiplicative normalization or pseudo division, and some early publications describing it are the works by De Lugish and Meggitt. The latter indicates that the origin is basically Henry Briggs's method for computing common logarithms.
B. de Lugish. "A Class of Algorithms for Automatic Evaluation of Functions and Computations in a Digital Computer". PhD thesis, Dept. of Computer Science, University of Illinois, Urbana, 1970.
J. E. Meggitt. "Pseudo division and pseudo multiplication processes". IBM Journal of Research and Development, Vol. 6, No. 2, April 1962, pp. 210-226
As the chosen set of factors comprises 2i and (1+2-i) the necessary multiplications can be performed without the need for a multiplication instruction: the products can be computed by either shift or shift plus add.
Since the inputs u and p are purely fractional numbers with 16 bits, we may want to chose a 5.16 fixed-point result for the logarithm. By simply dividing the two logarithm values, we remove the fixed-point scale factor, and apply a floor() operation at the same time, because for positive numbers, floor(x) is identical to trunc(x) and integer division is truncating.
Note that the fixed-point computation of the logarithm results in large relative error for inputs near 1. This in turn means the entire function computed using fixed-point arithmetic may deliver results significantly different from the reference if p is small. An example of this is the following test case: u=55af p=0052 res=848 ref=874.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
/* input x is a 0.16 fixed-point number in [0,1)
function returns -log2(x) as a 5.16 fixed-point number in (0, 16]
*/
uint32_t nlog2_16 (uint16_t x)
{
uint32_t r = 0;
uint32_t t, a = x;
/* try factors 2**i with i = 8, 4, 2, 1 */
if ((t = a << 8 ) < 0x10000) { a = t; r += 0x80000; }
if ((t = a << 4 ) < 0x10000) { a = t; r += 0x40000; }
if ((t = a << 2 ) < 0x10000) { a = t; r += 0x20000; }
if ((t = a << 1 ) < 0x10000) { a = t; r += 0x10000; }
/* try factors (1+2**(-i)) with i = 1, .., 16 */
if ((t = a + (a >> 1)) < 0x10000) { a = t; r += 0x095c0; }
if ((t = a + (a >> 2)) < 0x10000) { a = t; r += 0x0526a; }
if ((t = a + (a >> 3)) < 0x10000) { a = t; r += 0x02b80; }
if ((t = a + (a >> 4)) < 0x10000) { a = t; r += 0x01664; }
if ((t = a + (a >> 5)) < 0x10000) { a = t; r += 0x00b5d; }
if ((t = a + (a >> 6)) < 0x10000) { a = t; r += 0x005ba; }
if ((t = a + (a >> 7)) < 0x10000) { a = t; r += 0x002e0; }
if ((t = a + (a >> 8)) < 0x10000) { a = t; r += 0x00171; }
if ((t = a + (a >> 9)) < 0x10000) { a = t; r += 0x000b8; }
if ((t = a + (a >> 10)) < 0x10000) { a = t; r += 0x0005c; }
if ((t = a + (a >> 11)) < 0x10000) { a = t; r += 0x0002e; }
if ((t = a + (a >> 12)) < 0x10000) { a = t; r += 0x00017; }
if ((t = a + (a >> 13)) < 0x10000) { a = t; r += 0x0000c; }
if ((t = a + (a >> 14)) < 0x10000) { a = t; r += 0x00006; }
if ((t = a + (a >> 15)) < 0x10000) { a = t; r += 0x00003; }
if ((t = a + (a >> 16)) < 0x10000) { a = t; r += 0x00001; }
return r;
}
/* Compute floor(log(u)/log(1-p)) for 0 < u < 1 and 0 < p < 1,
where 'u' and 'p' are represented as 0.16 fixed-point numbers
Result is an integer in range [0, 1048676]
*/
uint32_t func (uint16_t u, uint16_t p)
{
uint16_t one_minus_p = 0x10000 - p; // 1.0 - p
uint32_t log_u = nlog2_16 (u);
uint32_t log_p = nlog2_16 (one_minus_p);
uint32_t res = log_u / log_p; // divide and floor in one go
return res;
}
The maximum value of this function basically depends on the precision limit; that is, how arbitrarily close to the limits (u -> 0) or (1 - p -> 1) the fixed point values can be.
If we assume (k) fractional bits, e.g., with the limits: u = (2^-k) and 1 - p = 1 - (2^-k),
then the maximum value is: k / (k - log2(2^k - 1))
(As the ratio of natural logarithms, we are free to use any base e.g., lb(x) or log2)
Unlike njuffa's answer, I went with a lookup table approach, settling on k = 10 fractional bits to represent 0 < frac(u) < 1024 and 0 < frac(p) < 1024. This requires a log table with 2^k entries. Using 32-bit table values, we're only looking at a 4KiB table.
Any more than that, and you are using enough memory that you could seriously consider using the relevant parts of a 'soft-float' library. e.g., k = 16 would yield a 256KiB LUT.
We're computing the values - log2(i / 1024.0) for 0 < i < 1024. Since these values are in the open interval (0, k), we only need 4 binary digits to store the integral part. So we store the precomputed LUT in 32-bit [4.28] fixed-point format:
uint32_t lut[1024]; /* never use lut[0] */
for (uint32_t i = 1; i < 1024; i++)
lut[i] = (uint32_t) (- (log2(i / 1024.0) * (268435456.0));
Given: u, p represented by [0.10] fixed-point values in [1, 1023] :
uint32_t func (uint16_t u, uint16_t p)
{
/* assert: 0 < u, p < 1024 */
return lut[u] / lut[1024 - p];
}
We can easily test all valid (u, p) pairs against the 'naive' floating-point evaluation:
floor(log(u / 1024.0) / log(1.0 - p / 1024.0))
and only get a mismatch (+1 too high) on the following cases:
u = 193, p = 1 : 1708 vs 1707 (1.7079978488147417e+03)
u = 250, p = 384 : 3 vs 2 (2.9999999999999996e+00)
u = 413, p = 4 : 232 vs 231 (2.3199989016957960e+02)
u = 603, p = 1 : 542 vs 541 (5.4199909906444600e+02)
u = 680, p = 1 : 419 vs 418 (4.1899938077226307e+02)
Finally, it turns out that using the natural logarithm in a [3.29] fixed-point format gives us even higher precision, where:
lut[i] = (uint32_t) (- (log(i / 1024.0) * (536870912.0));
only yields a single 'mismatch', though 'bignum' precision suggests it's correct:
u = 250, p = 384 : 3 vs 2 (2.9999999999999996e+00)
I am looking for an efficient algorithm to find nth root of a number. The answer must be an integer. I have found that newtons method and bisection method are popular methods. Are there any efficient and simple methods for integer output?
#include <math.h>
inline int root(int input, int n)
{
return round(pow(input, 1./n));
}
This works for pretty much the whole integer range (as IEEE754 8-byte doubles can represent the whole 32-bit int range exactly, which are the representations and sizes that are used on pretty much every system). And I doubt any integer based algorithm is faster on non-ancient hardware. Including ARM. Embedded controllers (the microwave washing machine kind) might not have floating point hardware though. But that part of the question was underspecified.
I know this thread is probably dead, but I don't see any answers I like and that bugs me...
int root(int a, int n) {
int v = 1, bit, tp, t;
if (n == 0) return 0; //error: zeroth root is indeterminate!
if (n == 1) return a;
tp = iPow(v,n);
while (tp < a) { // first power of two such that v**n >= a
v <<= 1;
tp = iPow(v,n);
}
if (tp == a) return v; // answer is a power of two
v >>= 1;
bit = v >> 1;
tp = iPow(v, n); // v is highest power of two such that v**n < a
while (a > tp) {
v += bit; // add bit to value
t = iPow(v, n);
if (t > a) v -= bit; // did we add too much?
else tp = t;
if ( (bit >>= 1) == 0) break;
}
return v; // closest integer such that v**n <= a
}
// used by root function...
int iPow(int a, int e) {
int r = 1;
if (e == 0) return r;
while (e != 0) {
if ((e & 1) == 1) r *= a;
e >>= 1;
a *= a;
}
return r;
}
This method will also work with arbitrary precision fixed point math in case you want to compute something like sqrt(2) to 100 decimal places...
I question your use of "algorithm" when speaking of C programs. Programs and algorithms are not the same (an algorithm is mathematical; a C program is expected to be implementing some algorithm).
But on current processors (like in recent x86-64 laptops or desktops) the FPU is doing fairly well. I guess (but did not benchmark) that a fast way of computing the n-th root could be,
inline unsigned root(unsigned x, unsigned n) {
switch (n) {
case 0: return 1;
case 1: return x;
case 2: return (unsigned)sqrt((double)x);
case 3: return (unsigned)cbrt((double)x);
default: return (unsigned) pow (x, 1.0/n);
}
}
(I made a switch because many processors have hardware to compute sqrt and some have hardware to compute cbrt ..., so you should prefer these when relevant...).
I am not sure that n-th root of a negative number makes sense in general. So my root function takes some unsigned x and returns some unsigned number.
Here is an efficient general implementation in C, using a simplified version of the "shifting nth root algorithm" to compute the floor of the nth root of x:
uint64_t iroot(const uint64_t x, const unsigned n)
{
if ((x == 0) || (n == 0)) return 0;
if (n == 1) return x;
uint64_t r = 1;
for (int s = ((ilog2(x) / n) * n) - n; s >= 0; s -= n)
{
r <<= 1;
r |= (ipow(r|1, n) <= (x >> s));
}
return r;
}
It needs this function to compute the nth power of x (using the method of exponentiation by squaring):
uint64_t ipow(uint64_t x, unsigned n)
{
if (x <= 1) return x;
uint64_t y = 1;
for (; n != 0; n >>= 1, x *= x)
if (n & 1)
y *= x;
return y;
}
and this function to compute the floor of base-2 logarithm of x:
int ilog2(uint64_t x)
{
#if __has_builtin(__builtin_clzll)
return 63 - ((x != 0) * (int)__builtin_clzll(x)) - ((x == 0) * 64);
#else
int y = -(x == 0);
for (unsigned k = 64 / 2; k != 0; k /= 2)
if ((x >> k) != 0)
{ x >>= k; y += k; }
return y;
#endif
}
Note: This assumes that your compiler understands GCC's __has_builtin test and that your compiler's uint64_t type is the same size as an unsigned long long.
You can try this C function to get the nth_root of an unsigned integer :
unsigned initial_guess_nth_root(unsigned n, unsigned nth){
unsigned res = 1;
for(; n >>= 1; ++res);
return nth ? 1 << (res + nth - 1) / nth : 0 ;
}
// return a number that, when multiplied by itself nth times, makes N.
unsigned nth_root(const unsigned n, const unsigned nth) {
unsigned a = initial_guess_nth_root(n , nth), b, c, r = nth ? a + (n > 0) : n == 1 ;
for (; a < r; b = a + (nth - 1) * r, a = b / nth)
for (r = a, a = n, c = nth - 1; c && (a /= r); --c);
return r;
}
Example of output :
24 == (int) pow(15625, 1.0/3)
25 == nth_root(15625, 3)
0 == nth_root(0, 0)
1 == nth_root(1, 0)
4 == nth_root(4096, 6)
13 == nth_root(18446744073709551614, 17) // 64-bit 20 digits
11 == nth_root(340282366920938463463374607431768211454, 37) // 128-bit 39 digits
Here is the github source.
I want to check if the / operator has no remainder or not:
int x = 0;
if (x = 16 / 4), if there is no remainder:
then x = x - 1;
if (x = 16 / 5), if remainder is not zero:
then x = x + 1;
How to check if there are remainder in C? and
How to implement it?
Frist, you need % remainder operator:
if (x = 16 % 4){
printf("remainder in X");
}
Note: it will not work with float/double, in that case you need to use fmod (double numer, double denom);.
Second, to implement it as you wish:
if (x = 16 / 4), if there is no remainder, x = x - 1;
If (x = 16 / 5), then x = x + 1;
Useing , comma operator, you can do it in single step as follows (read comments):
int main(){
int x = 0, // Quotient.
n = 16, // Numerator
d = 4; // Denominator
// Remainder is not saved
if(x = n / d, n % d) // == x = n / d; if(n % d)
printf("Remainder not zero, x + 1 = %d", (x + 1));
else
printf("Remainder is zero, x - 1 = %d", (x - 1));
return 1;
}
Check working codes #codepade: first, second, third.
Notice in if-condition I am using Comma Operator: ,, to understand , operator read: comma operator with an example.
If you want to find the remainder of an integer division then you can use the modulus(%):
if( 16 % 4 == 0 )
{
x = x - 1 ;
}
else
{
x = x +1 ;
}
use the % operator to find the remainder of a division
if (number % divisor == 0)
{
//code for perfect divisor
}
else
{
//the number doesn't divide perfectly by divisor
}
use modulous operator for this purpose.
if(x%y == 0) then there is no remainder.
In division operation, if the result is floating point, then only integer part will be returned and decimal part will be discarded.
you can use Modulous operator which deals with remainder.
The modulus operator (represented by the % symbol in C) computes the remainder. So:
x = 16 % 4;
x will be 0.
X = 16 % 5;
x will be 1