How to find perfect numbers upto 10^18 in C? - math

I have a C code off finding large perfect numbers below,
#include <stdio.h>
int main ()
{
unsigned long long num,i,sum;
while (scanf ("%llu",&num) != EOF && num)
{
sum = 1;
for (i=2; i*i<=num; i++)
{
if (num % i == 0)
{
if (i*i == num)
sum += i;
else
sum += (i + num/i);
}
}
if (sum == num)
printf ("Perfect\n");
else if (sum > num)
printf ("Abundant\n");
else
printf ("Deficient\n");
}
return 0;
}
I tried to find whether a number is perfect, abundant or deficient. I run a loop upto the square root of numto minimize the runtime. It works fine <= 10^15 but for the larger values it takes too long time to execute.
For example,for the following input sets,
8
6
18
1000000
1000000000000000
0
this code shows the following outputs,
Deficient
Perfect
Abundant
Abundant
Abundant
But, for 10^16 it doesn't respond quickly.
So, is there any better way to find a perfect number for too long values? Or is there any better algorithm to implement here??? :)

Yes, there is a better algorithm.
Your algorithm is basically the simple one--adding up the divisors of a number to find... the sum of the divisors of a number (excluding itself). But you can use the number-theoretic formula for finding the sum of the divisors of a number (including itself). If the prime numbers dividing n are p1, p2, ..., pk and the powers of those primes in the canonical decomposition of n are a1, a2, ..., ak, then the sum of the divisors of n is
(p1**(a1+1) - 1) / (p1 - 1) * (p2**(a2+1) - 1) / (p2 - 1) * ...
* (pk**(ak+1) - 1) / (pk - 1)
You can find the prime divisors and their exponents more quickly than finding all the divisors of n. Subtract n from that expression above and you get the sum you want.
There are some tricks, of course, to find the pis and ais more efficiently: I'll leave that to you.
By the way, if your purpose is just to find the perfect numbers, as in your title, you would do better to use Euclid's formula for even prime numbers. Find the Mersenne prime numbers by examining all 2**p-1 for prime p to see if they are prime--there are shortcuts to doing this as well--then constructing a perfect number from that Mersenne prime. This would leave out any odd perfect numbers, though. If you find any, let the mathematical community know--that would make you world famous.
Of course, the fastest way of all to find perfect numbers is to use the lists already made of some of them.

It is a matter of factorization of numbers. You can read more here: https://en.wikipedia.org/wiki/Integer_factorization
Unfortunately no good news for you - the bigger the number gets, the longer it takes.
To start with your code, try not to multiply i*i each iteration.
Instead of:
for (i=2; i*i<=num; i++)
calculate square root of num first, and then compare
i <= square_root_of_num in the loop.

// Program to determine whether perfect or not
# include <bits/stdc++.h>
using namespace std;
map<long long int, int> mp; // to store prime factors and there frequency
void primeFactors(long long int n)
{
// counting the number of 2s that divide n
while (n%2 == 0)
{
mp[2] = mp[2]+1;
n = n/2;
}
long long int root = sqrt(n);
// n must be odd at this point. So we can skip every even numbers next
for (long long int i = 3; i <= root; i = i+2)
{
// While i divides n, count frequency of i prime factor and divide n
while (n%i == 0)
{
mp[i] = mp[i]+1;
n = n/i;
}
}
// This condition is to handle the case whien n is a prime number
// greater than 2
if (n > 2)
{
mp[n] = mp[n]+1;
}
}
long long int pow(long long int base, long long int exp)
{
long long int result = 1;
base = base;
while (exp>0)
{
if (exp & 1)
result = (result*base);
exp >>= 1;
base = (base*base);
}
return result;
}
int main ()
{
long long num, p, a, sum;
while (scanf ("%lld",&num) != EOF && num)
{
primeFactors(num);
sum = 1;
map<long long int, int> :: iterator i;
for(i=mp.begin(); i!=mp.end(); i++)
{
p = i->first;
a = i->second;
sum = sum*((pow(p,a+1)-1)/(p-1));
}
if (sum == 2*num)
printf ("Perfect\n");
else if (sum > num)
printf ("Abundant\n");
else
printf ("Deficient\n");
mp.clear();
}
return 0;
}

Related

Carmichael Number using Pari

Trying to write Pari code to solve the above question.
I've got no experience in using Pari, but here's some useful advice:
n is Carmichael if and only if it is composite and, for all a with 1 < a < n which are relatively prime to n, the congruence a^(n-1) = 1 (mod n) holds. To use this definition directly, you need:
1) An efficient way to test if a and n are relatively prime
2) An efficient way to compute a^(n-1) (mod n)
For the first -- use the Euclidean algorithm for greatest common divisors. It is most efficiently computed in a loop, but can also be defined via the simple recurrence gcd(a,b) = gcd(b,a%b) with basis gcd(a,0) = a. In C this is just:
unsigned int gcd(unsigned int a, unsigned int b){
return b == 0? a : gcd(b, a%b);
}
For the second point -- almost the worst possible thing you can do when computing a^k (mod n) is to first compute a^k via repeated multiplication and to then mod the result by n. Instead -- use exponentiation by squaring, taking the remainder (mod n) at intermediate stages. It is a divide-and-conquer algorithm based on the observation that e.g. a^10 = (a^5)^2 and a^11 = (a^5)^2 * a. A simple C implementation is:
unsigned int modexp(unsigned int a, unsigned int p, unsigned int n){
unsigned long long b;
switch(p){
case 0:
return 1;
case 1:
return a%n;
default:
b = modexp(a,p/2,n);
b = (b*b) % n;
if(p%2 == 1) b = (b*a) % n;
return b;
}
}
Note the use of unsigned long long to guard against overflow in the calculation of b*b.
To test if n is Carmichael, you might as well first test if n is even and return 0 in that case. Otherwise, step through numbers, a, in the range 2 to n-1. First check if gcd(a,n) == 1 Note that if n is composite then you must have at least one a before you reach the square root of n with gcd(a,n) > 1). Keep a Boolean flag which keeps track of whether or not such an a has been encountered and if you exceed the square root without finding such an a, return 0. For those a with gcd(a,n) == 1, compute the modular exponentiation a^(n-1) (mod n). If this is ever different from 1, return 0. If your loop finishes checking all a below n without returning 0, then the number is Carmichael, so return 1. An implementation is:
int is_carmichael(unsigned int n){
int a,s;
int factor_found = 0;
if (n%2 == 0) return 0;
//else:
s = sqrt(n);
a = 2;
while(a < n){
if(a > s && !factor_found){
return 0;
}
if(gcd(a,n) > 1){
factor_found = 1;
}
else{
if(modexp(a,n-1,n) != 1){
return 0;
}
}
a++;
}
return 1; //anything that survives to here is a carmichael
}
A simple driver program:
int main(void){
unsigned int n;
for(n = 2; n < 100000; n ++){
if(is_carmichael(n)) printf("%u\n",n);
}
return 0;
}
output:
C:\Programs>gcc carmichael.c
C:\Programs>a
561
1105
1729
2465
2821
6601
8911
10585
15841
29341
41041
46657
52633
62745
63973
75361
This only takes about 2 seconds to run and matches the initial part of this list.
This is probably a somewhat practical method for checking if numbers up to a million or so are Carmichael numbers. For larger numbers, you should probably get yourself a good factoring algorithm and use Korseldt's criterion as described in the Wikipedia entry on Carmichael numbers.

How many zero total in 100 factorial

I have a homework that count total zero in n factorial. What should i do?
I only find way to count trailing of factorial
static int findTrailingZeros(int n)
{
// Initialize result
int count = 0;
// Keep dividing n by powers
// of 5 and update count
for (int i = 5; n / i >= 1; i *= 5)
count += n / i;
return count;
}
The total number of zeros in n! is given by sequence A027869 in the On-line Encyclopedia of Integer Sequences. There really seems to be no way to compute the total number of zeros in n! short of computing n! and counting the number of zeros. With a big int library, this is easy enough. A simple Python example:
import math
def zeros(n): return str(math.factorial(n)).count('0')
So, for example, zeros(100) evaluates to 30. For larger n you might want to skip the relatively expensive conversion to a string and get the 0-count arithmetically by repeatedly dividing by 10.
As you have noted, it is far easier to compute the number of trailing zeros. Your code, in Python, is essentially:
def trailing_zeros(n):
count = 0
p = 5
while p <= n:
count += n//p
p *= 5
return count
As a heuristic way to estimate the total number of zeros, you can first count the number of trailing zeros, subtract that from the number of digits in n!, subtract an additional 2 from this difference (since neither the first digit of n! nor the final digit before the trailing zeros are candidate positions for non-trailing zeros) and guess that 1/10 of these digits will in fact be zeros. You can use Stirling's formula to estimate the number of digits in n!:
def num_digits(n):
#uses Striling's formula to estimate the number of digits in n!
#this formula, known as, Kamenetsky's formula, gives the exact count below 5*10^7
if n == 0:
return 1
else:
return math.ceil(math.log10(2*math.pi*n)/2 + n *(math.log10(n/math.e)))
Hence:
def est_zeros(n):
#first compute the number of candidate postions for non-trailing zerpos:
internal_digits = max(0,num_digits(n) - trailing_zeros(n) - 2)
return trailing_zeros(n) + internal_digits//10
For example est_zeros(100) evaluates to 37, which isn't very good, but then there is no reason to think that this estimation is any better than asymptotic (though proving that it is asymptotically correct would be very difficult, I don't actually know if it is). For larger numbers it seems to give reasonable results. For example zeros(10000) == 5803 and est_zeros == 5814.
How about this then.
count = 0
s = str(fact)
for i in s:
if i=="0":
count +=1
print(count)
100! is a big number:
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
To be more precise it need ~525 bit and can not be computed without some form of bigint math.
However trailing zeros might be computable on normal integers:
The idea is to limit the result to still fit into your data type. So after each iteration test if the result is divisible by 10. If it is increment your zeros counter and divide the result by 10 while you can. The same goes for any primes except those that divide 10 so not: 2,5 (but without incrementing your zeros counter). This way you will have small sub-result and count of trailing zeros.
So if you do a 2,5 factorization of all the multiplicants in n! the min of the both exponents of 2,5 will be the number of trailing zeros as each pair produces one zero digit (2*5 = 10). If you realize that exponent of 5 is always smaller or equal than exponent of 2 its enough to do the factorization of 5 (just like you do in your updated code).
int fact_trailing_zeros(int n)
{
int i,n5;
for (n5=0,i=5;n>=i;i*=5) n5+=n/i;
return n5;
}
With results:
Trailing zeors of n!
10! : 2
100! : 24
1000! : 249
10000! : 2499
100000! : 24999
1000000! : 249998
10000000! : 2499999
100000000! : 24999999
[ 0.937 ms]
However 100! contains also non trailing zeros and to compute those I see no other way than compute the real thing on a bigint math ... but that does not mean there is no workaround like for trailing zeros...
If it helps here are computed factorials up to 128! so you can check your results:
Fast exact bigint factorial
In case n is bounded to small enough value you can use LUT holding all the factorials up to the limit as strings or BCD and just count the zeros from there... or even have just the final results as a LUT ...
Here some bad code, but it works. You have to use TrailingZeros() only
public static int TrailingZeros(int n)
{
var fac = Factorial(n);
var num = SplitNumber(fac);
Array.Reverse(num);
int i = 0;
int res = 0;
while (num[i] == 0)
{
if (num[i] == 0)
{
res++;
}
i++;
}
return res;
}
public static BigInteger Factorial(int number)
{
BigInteger factorial = 1; // значение факториала
for (int i = 2; i <= number; i++)
{
factorial = factorial * i;
}
return factorial;
}
public static int[] SplitNumber(BigInteger number)
{
var result = new int[0];
int count = 0;
while (number > 0)
{
Array.Resize(ref result, count + 1);
result[count] = (int)(number % 10);
number = number / 10;
count++;
}
Array.Reverse(result);
return result;
}

Finding (a ^ x) % m from a % m. This is about utilizing a % m to calculate (a ^ x) % m. % is the modulus operator [duplicate]

I want to calculate ab mod n for use in RSA decryption. My code (below) returns incorrect answers. What is wrong with it?
unsigned long int decrypt2(int a,int b,int n)
{
unsigned long int res = 1;
for (int i = 0; i < (b / 2); i++)
{
res *= ((a * a) % n);
res %= n;
}
if (b % n == 1)
res *=a;
res %=n;
return res;
}
You can try this C++ code. I've used it with 32 and 64-bit integers. I'm sure I got this from SO.
template <typename T>
T modpow(T base, T exp, T modulus) {
base %= modulus;
T result = 1;
while (exp > 0) {
if (exp & 1) result = (result * base) % modulus;
base = (base * base) % modulus;
exp >>= 1;
}
return result;
}
You can find this algorithm and related discussion in the literature on p. 244 of
Schneier, Bruce (1996). Applied Cryptography: Protocols, Algorithms, and Source Code in C, Second Edition (2nd ed.). Wiley. ISBN 978-0-471-11709-4.
Note that the multiplications result * base and base * base are subject to overflow in this simplified version. If the modulus is more than half the width of T (i.e. more than the square root of the maximum T value), then one should use a suitable modular multiplication algorithm instead - see the answers to Ways to do modulo multiplication with primitive types.
In order to calculate pow(a,b) % n to be used for RSA decryption, the best algorithm I came across is Primality Testing 1) which is as follows:
int modulo(int a, int b, int n){
long long x=1, y=a;
while (b > 0) {
if (b%2 == 1) {
x = (x*y) % n; // multiplying with base
}
y = (y*y) % n; // squaring the base
b /= 2;
}
return x % n;
}
See below reference for more details.
1) Primality Testing : Non-deterministic Algorithms – topcoder
Usually it's something like this:
while (b)
{
if (b % 2) { res = (res * a) % n; }
a = (a * a) % n;
b /= 2;
}
return res;
The only actual logic error that I see is this line:
if (b % n == 1)
which should be this:
if (b % 2 == 1)
But your overall design is problematic: your function performs O(b) multiplications and modulus operations, but your use of b / 2 and a * a implies that you were aiming to perform O(log b) operations (which is usually how modular exponentiation is done).
Doing the raw power operation is very costly, hence you can apply the following logic to simplify the decryption.
From here,
Now say we want to encrypt the message m = 7, c = m^e mod n = 7^3 mod 33
= 343 mod 33 = 13. Hence the ciphertext c = 13.
To check decryption we compute m' = c^d mod n = 13^7 mod 33 = 7. Note
that we don't have to calculate the full value of 13 to the power 7
here. We can make use of the fact that a = bc mod n = (b mod n).(c mod
n) mod n so we can break down a potentially large number into its
components and combine the results of easier, smaller calculations to
calculate the final value.
One way of calculating m' is as follows:- Note that any number can be
expressed as a sum of powers of 2. So first compute values of 13^2,
13^4, 13^8, ... by repeatedly squaring successive values modulo 33. 13^2
= 169 ≡ 4, 13^4 = 4.4 = 16, 13^8 = 16.16 = 256 ≡ 25. Then, since 7 = 4 + 2 + 1, we have m' = 13^7 = 13^(4+2+1) = 13^4.13^2.13^1 ≡ 16 x 4 x 13 = 832
≡ 7 mod 33
Are you trying to calculate (a^b)%n, or a^(b%n) ?
If you want the first one, then your code only works when b is an even number, because of that b/2. The "if b%n==1" is incorrect because you don't care about b%n here, but rather about b%2.
If you want the second one, then the loop is wrong because you're looping b/2 times instead of (b%n)/2 times.
Either way, your function is unnecessarily complex. Why do you loop until b/2 and try to multiply in 2 a's each time? Why not just loop until b and mulitply in one a each time. That would eliminate a lot of unnecessary complexity and thus eliminate potential errors. Are you thinking that you'll make the program faster by cutting the number of times through the loop in half? Frankly, that's a bad programming practice: micro-optimization. It doesn't really help much: You still multiply by a the same number of times, all you do is cut down on the number of times testing the loop. If b is typically small (like one or two digits), it's not worth the trouble. If b is large -- if it can be in the millions -- then this is insufficient, you need a much more radical optimization.
Also, why do the %n each time through the loop? Why not just do it once at the end?
Calculating pow(a,b) mod n
A key problem with OP's code is a * a. This is int overflow (undefined behavior) when a is large enough. The type of res is irrelevant in the multiplication of a * a.
The solution is to ensure either:
the multiplication is done with 2x wide math or
with modulus n, n*n <= type_MAX + 1
There is no reason to return a wider type than the type of the modulus as the result is always represent by that type.
// unsigned long int decrypt2(int a,int b,int n)
int decrypt2(int a,int b,int n)
Using unsigned math is certainly more suitable for OP's RSA goals.
Also see Modular exponentiation without range restriction
// (a^b)%n
// n != 0
// Test if unsigned long long at least 2x values bits as unsigned
#if ULLONG_MAX/UINT_MAX - 1 > UINT_MAX
unsigned decrypt2(unsigned a, unsigned b, unsigned n) {
unsigned long long result = 1u % n; // Insure result < n, even when n==1
while (b > 0) {
if (b & 1) result = (result * a) % n;
a = (1ULL * a * a) %n;
b >>= 1;
}
return (unsigned) result;
}
#else
unsigned decrypt2(unsigned a, unsigned b, unsigned n) {
// Detect if UINT_MAX + 1 < n*n
if (UINT_MAX/n < n-1) {
return TBD_code_with_wider_math(a,b,n);
}
a %= n;
unsigned result = 1u % n;
while (b > 0) {
if (b & 1) result = (result * a) % n;
a = (a * a) % n;
b >>= 1;
}
return result;
}
#endif
int's are generally not enough for RSA (unless you are dealing with small simplified examples)
you need a data type that can store integers up to 2256 (for 256-bit RSA keys) or 2512 for 512-bit keys, etc
Here is another way. Remember that when we find modulo multiplicative inverse of a under mod m.
Then
a and m must be coprime with each other.
We can use gcd extended for calculating modulo multiplicative inverse.
For computing ab mod m when a and b can have more than 105 digits then its tricky to compute the result.
Below code will do the computing part :
#include <iostream>
#include <string>
using namespace std;
/*
* May this code live long.
*/
long pow(string,string,long long);
long pow(long long ,long long ,long long);
int main() {
string _num,_pow;
long long _mod;
cin>>_num>>_pow>>_mod;
//cout<<_num<<" "<<_pow<<" "<<_mod<<endl;
cout<<pow(_num,_pow,_mod)<<endl;
return 0;
}
long pow(string n,string p,long long mod){
long long num=0,_pow=0;
for(char c: n){
num=(num*10+c-48)%mod;
}
for(char c: p){
_pow=(_pow*10+c-48)%(mod-1);
}
return pow(num,_pow,mod);
}
long pow(long long a,long long p,long long mod){
long res=1;
if(a==0)return 0;
while(p>0){
if((p&1)==0){
p/=2;
a=(a*a)%mod;
}
else{
p--;
res=(res*a)%mod;
}
}
return res;
}
This code works because ab mod m can be written as (a mod m)b mod m-1 mod m.
Hope it helped { :)
use fast exponentiation maybe..... gives same o(log n) as that template above
int power(int base, int exp,int mod)
{
if(exp == 0)
return 1;
int p=power(base, exp/2,mod);
p=(p*p)% mod;
return (exp%2 == 0)?p:(base * p)%mod;
}
This(encryption) is more of an algorithm design problem than a programming one. The important missing part is familiarity with modern algebra. I suggest that you look for a huge optimizatin in group theory and number theory.
If n is a prime number, pow(a,n-1)%n==1 (assuming infinite digit integers).So, basically you need to calculate pow(a,b%(n-1))%n; According to group theory, you can find e such that every other number is equivalent to a power of e modulo n. Therefore the range [1..n-1] can be represented as a permutation on powers of e. Given the algorithm to find e for n and logarithm of a base e, calculations can be significantly simplified. Cryptography needs a tone of math background; I'd rather be off that ground without enough background.
For my code a^k mod n in php:
function pmod(a, k, n)
{
if (n==1) return 0;
power = 1;
for(i=1; i<=k; $i++)
{
power = (power*a) % n;
}
return power;
}
#include <cmath>
...
static_cast<int>(std::pow(a,b))%n
but my best bet is you are overflowing int (IE: the number is two large for the int) on the power I had the same problem creating the exact same function.
I'm using this function:
int CalculateMod(int base, int exp ,int mod){
int result;
result = (int) pow(base,exp);
result = result % mod;
return result;
}
I parse the variable result because pow give you back a double, and for using mod you need two variables of type int, anyway, in a RSA decryption, you should just use integer numbers.

How to calculate Least common multiple of {1, 2, 3, .........., n}?

How to find LCM of {1, 2, ..., n} where 0 < n < 10001 in fastest possible way. The one way is to calculate n! / gcd (1,2,.....,n) but this can be slow as number of testcases are t < 501 and the output should be LCM ( n! ) % 1000000007
Code for the same is:
#include<bits/stdc++.h>
using namespace std;
#define p 1000000007;
int fact[10001] = {1};
int gcd[10001] = {1};
int main()
{
int i, j;
for( i = 2;i < 10001; i++){
fact[i] = ( i * fact[i-1]) % p;
}
for(i=2 ;i < 10001; i++){
gcd[i] =__gcd( gcd[i-1], i );
}
int t;
cin >> t;
while( t-- ) {
int n;
cin >> n;
int res = ( fact[n] / gcd[n] );
cout << res << endl;
}
return 0;
}
But this code is not performing as well. Why?
Your current solution is not correct, as has been mentioned in the comments.
One way to solve this is to realize that the LCM of those numbers is just the product of all the "largest" powers of distinct primes less than or equal to n. That is, find each prime p less than or equal to n, then find the largest power of each of those primes such that it's still less than or equal to n, and multiply those together. For a given p, said power can be expressed in pseudocode as:
p ** math.Floor(math.Log(n) / math.Log(p))
Here's an implementation in Golang that returns immediately:
http://play.golang.org/p/8s4eE_CQ9Y
$ time go run lcm.go
5793339670287642968692270879166240098634860297998518825393138351148979300145773182308832598
<several lines later>
800000
real 0m0.225s
user 0m0.173s
sys 0m0.044s
For completeness, the full code from that playground link is pasted here:
package main
import (
"fmt"
"math"
"math/big"
)
func main() {
n := 10001
primes := make([]int, 1, n)
primes[0] = 2
SIEVE:
for i := 3; i <= n; i++ {
for _, p := range primes {
if i%p == 0 {
continue SIEVE
}
}
primes = append(primes, i)
}
logN := math.Log(float64(n))
lcm := big.NewInt(1)
for _, p := range primes {
floatP := float64(p)
e := math.Floor(logN / math.Log(floatP))
lcm.Mul(lcm, big.NewInt(int64(math.Pow(floatP, e))))
}
fmt.Println(lcm)
}
I would calculate this in completely different way: the LCM of {1,...,n} is a product of all primes p[i]<=n, each in power floor(log(n)/log(p[i])). This product is divisible by all numbers up to n, and this is the least such number. Your main trouble is to calculate table of primes then.
I'm going to suggest something less dynamic, but it will increase your speed dramatically. Set up a factorial table (perhaps an array) and store pre-calculated factorial integer representations there. That way, it's a simple O(1) operation, versus O(n). Here's a reference table, but you may also precalculate those yourself: http://www.tsm-resources.com/alists/fact.html It's okay to do so, because those values will never change. If we're talking optimization for speed, then why not store the values we know, rather than calculate them each time?
If, however, you're opposed to storing these calculations beforehand, I suggest looking at optimized algorithms and work your way from there:
Here are two excellent resources for faster factorial calculation algorithms:
http://www.luschny.de/math/factorial/conclusions.html
http://www.luschny.de/math/factorial/scala/FactorialScalaCsharp.htm
This is very simple but it seems to run fast enough. Probably Amit Kumar Gupta's idea is faster. Stack overflow around n = 9500 on my machine but that could be fixed by memoizing the function and building up the memo from small numbers to larger numbers. I didn't take the modulus but that fix is easy, particularly if the modulus is prime. Is it?
import java.math.BigInteger;
public class LCM {
// compute f(n) = lcm(1,...n)
public static BigInteger f(int n) {
if (n == 1) return BigInteger.ONE;
BigInteger prev = f(n-1);
return prev.divide(prev.gcd(BigInteger.valueOf(n)))
.multiply(BigInteger.valueOf(n));
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
System.out.println("f(" + n + ") = " + f(n));
}
}

Finding the tenth's place equivalent of an integer

How does one, computationally and dynamically, derive the 'ths' place equivalent of a whole integer? e.g.:
187 as 0.187
16 as 0.16
900041 as 0.900041
I understand one needs to compute the exact th's place. I know one trick is to turn the integer into a string, count how many places there are (by how many individual characters there are) and then create our future value to multiply against by the tenth's value derived - like how we would on pen and paper - such as:
char integerStr[7] = "186907";
int strLength = strlen(integerStr);
double thsPlace = 0.0F;
for (int counter = 0; counter < strLength; ++counter) {
thsPlace = 0.1F * thsPlace;
}
But what is a non-string, arithmetic approach to solving this?
pseudocode:
n / pow(10, floor(log10(n))+1)
Divide the original value by 10 repeatedly until it's less than one:
int x = 69105;
double result = (double) x;
while (x > 1.0) x /= 10.0;
/* result = 0.69105 */
Note that this won't work for negative values; for those, you need to perform the algorithm on the absolute value and then negate the result.
[edited for strange indenting]
I'm not sure exactly what you mean with your question, but here's what I would do:
int placeValue(int n)
{
if (n < 10)
{
return 1;
}
else
{
return placeValue(n / 10) + 1;
}
}
[This is a recursive method]
I don't know how performant the pow(10, x) version is, but you could try to do most of this with integer arithmetic. Assuming we are only dealing with positive values or 0 (use the absolute value, if necessary):
int divisor = 1;
while (divisor < x)
divisor *= 10;
if (divisor > 0)
return (double)x / divisor;
Note that the above needs some safeguards, i.e. checking if divisor may have overflow (in that case, it would be negative), if x is positive, etc. But I assume you can do that yourself.

Resources