I am a c++ newbie, and start learning it by learning algorithm at the same time. However, I encountered some problem when writing this algorithm --- the number overflows, which is quite different to the overflow I thought. To solve the problem, I searched for a long time, but end up in no use. Here is my code:
#include <iostream>
using namespace std;
long long Fs[101];
long long F(int N) {
if (Fs[N] != -1) {
return Fs[N];
}
int res = F(N - 1) + F(N - 2);
Fs[N] = res;
return res;
}
void main() {
// initialize Fs array
for (auto& item : Fs) {
item = -1;
}
Fs[0] = 0;
Fs[1] = 1;
cout << F(60) << endl;
cout << endl;
for (auto& item : Fs) {
cout << item << endl;
}
}
Part of the result is shown here:
165580141
267914296
433494437
701408733
1134903170
1836311903
-1323752223
512559680
-811192543
Question:
You can see that the overflow number is quite small than the minimum value of long long type. Why this happened?
Appendix
I found some way to print the overflow index of unsigned type when generating fibonacci, here is the code:
#include <iostream>
#include <limits>
using namespace std;
#define outFibonacci(nType) { int i = 1;\
while (i++)\
if (Fibonacci<nType>(i+1)==Fibonacci<nType>(i+2)){\
cout<<"F("<<i<<")\t= "<<Fibonacci<nType>(i)<<endl;\
break;\
}\
cout<< "Max Num\t= " << numeric_limits<nType>::max() << endl << endl;\
}
template<typename _T> _T Fibonacci(_T n){
_T f, f1, f2;
f = f1 = f2 = 1;
for (auto i=3; i<=n; ++i){
f = f1 + f2;
if (f<f2){ // Set overflow condition
f=-1;
break;
}
f1 = f2;
f2 = f;
}
return f;
}
int main(void)
{
outFibonacci(unsigned short);
outFibonacci(unsigned int);
outFibonacci(unsigned long);
outFibonacci(unsigned long long);
outFibonacci(size_t);
return 0;
}
and here is my result:
F(24) = 46368
Max Num = 65535
F(47) = 2971215073
Max Num = 4294967295
F(47) = 2971215073
Max Num = 4294967295
F(93) = 12200160415121876738
Max Num = 18446744073709551615
F(93) = 12200160415121876738
Max Num = 18446744073709551615
This line in your function int res = F(N - 1) + F(N - 2); makes your result an int, which is then casted to long long. so the overflow occurs here. Should be flagged by some compilers flags tho.
long long F(int N) {
if (Fs[N] != -1) {
return Fs[N];
}
// int res = F(N - 1) + F(N - 2); // HERE !
long long res = F(N - 1) + F(N - 2);
Fs[N] = res;
return res;
}
Related
Among the given input of two numbers, check if the second number is exactly the next prime number of the first number. If so return "YES" else "NO".
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int nextPrime(int x){
int y =x;
for(int i=2; i <=sqrt(y); i++){
if(y%i == 0){
y = y+2;
nextPrime(y);
return (y);
}
}
return y;
}
int main()
{
int n,m, x(0);
cin >> n >> m;
x = n+2;
if(n = 2 && m == 3){
cout << "YES\n";
exit(0);
}
nextPrime(x) == m ? cout << "YES\n" : cout << "NO\n";
return 0;
}
Where is my code running wrong? It only returns true if next number is either +2 or +4.
Maybe it has something to do with return statement.
I can tell you two things you are doing wrong:
Enter 2 4 and you will check 4, 6, 8, 10, 12, 14, 16, 18, ... for primality forever.
The other thing is
y = y+2;
nextPrime(y);
return (y);
should just be
return nextPrime(y + 2);
Beyond that your loop is highly inefficient:
for(int i=2; i <=sqrt(y); i++){
Handle even numbers as special case and then use
for(int i=3; i * i <= y; i += 2){
Using a different primality test would also be faster. For example Miller-Rabin primality test:
#include <iostream>
#include <cstdint>
#include <array>
#include <ranges>
#include <cassert>
#include <bitset>
#include <bit>
// square and multiply algorithm for a^d mod n
uint32_t pow_n(uint32_t a, uint32_t d, uint32_t n) {
if (d == 0) __builtin_unreachable();
unsigned shift = std::countl_zero(d) + 1;
uint32_t t = a;
int32_t m = d << shift;
for (unsigned i = 32 - shift; i > 0; --i) {
t = ((uint64_t)t * t) % n;
if (m < 0) t = ((uint64_t)t * a) % n;
m <<= 1;
}
return t;
}
bool test(uint32_t n, unsigned s, uint32_t d, uint32_t a) {
uint32_t x = pow_n(a, d, n);
//std::cout << " x = " << x << std::endl;
if (x == 1 || x == n - 1) return true;
for (unsigned i = 1; i < s; ++i) {
x = ((uint64_t)x * x) % n;
if (x == n - 1) return true;
}
return false;
}
bool is_prime(uint32_t n) {
static const std::array witnesses{2u, 3u, 5u, 7u, 11u};
static const std::array bounds{
2'047u, 1'373'653u, 25'326'001u, 3'215'031'751u, UINT_MAX
};
static_assert(witnesses.size() == bounds.size());
if (n == 2) return true; // 2 is prime
if (n % 2 == 0) return false; // other even numbers are not
if (n <= witnesses.back()) { // I know the first few primes
return (std::ranges::find(witnesses, n) != std::end(witnesses));
}
// write n = 2^s * d + 1 with d odd
unsigned s = 0;
uint32_t d = n - 1;
while (d % 2 == 0) {
++s;
d /= 2;
}
// test widtnesses until the bounds say it's a sure thing
auto it = bounds.cbegin();
for (auto a : witnesses) {
//std::cout << a << " ";
if (!test(n, s, d, a)) return false;
if (n < *it++) return true;
}
return true;
}
And yes, that is an awful lot of code but it runs very few times.
Something to do with the return statement
I would say so
y = y+2;
nextPrime(y);
return (y);
can be replaced with
return nextPrime(y + 2);
Your version calls nextPrime but fails to do anything with the return value, instead it just returns y.
It would be more usual to code the nextPrime function with another loop, instead of writing a recursive function.
Question:
Given an array arr[] with N integers.
What is the maximum number of items that can be chosen from the array so that their GCD is greater than 1?
Example:
4
30 42 105 1
Answer: 3
Constransts
N <= 10^3
arr[i] <= 10^18
My take:
void solve(int i, int gcd, int chosen){
if(i > n){
maximize(res, chosen);
return;
}
solve(i+1, gcd, chosen);
if(gcd == -1) solve(i+1, arr[i], chosen+1);
else{
int newGcd = __gcd(gcd, arr[i]);
if(newGcd > 1) solve(i+1, newGcd, chosen+1);
}
}
After many tries, my code still clearly got TLE, is there any more optimized solution for this problem?
Interesting task you have. I implemented two variants of solutions.
All algorithms that are used in my code are: Greatest Common Divisor (through Euclidean Algorithm), Binary Modular Exponentiation, Pollard Rho, Trial Division, Fermat Primality Test.
First variant called SolveCommon() iteratively finds all possible unique factors of all numbers by computing pairwise Greatest Common Divisor.
When all possible unique factors are found one can compute count of each unique factor inside each number. Finally maximal count for any factor will be final answer.
Second variant called SolveFactorize() finds all factor by doing factorization of each number using three algorithms: Pollard Rho, Trial Division, Fermat Primality Test.
Pollard-Rho factorization algorithm is quite fast, it has time complexity O(N^(1/4)), so for 64-bit number it will take around 2^16 iterations. To compare, Trial Division algorithm has complexity of O(N^(1/2)) which is square times slower than Pollard Rho. So in code below Pollard Rho can handle 64 bit inputs, although not very fast.
First variant SolveCommon() is much faster than second SolveFactorize(), especially if numbers are quite large, timings are provided in console output after following code.
Code below as an example provides test of random 100 numbers each 20 bit. 64 bit 1000 numbers are too large to handle by SolveFactorize() method, but SolveCommon() method solves 1000 64-bit numbers within 1-2 seconds.
Try it online!
#include <cstdint>
#include <random>
#include <tuple>
#include <unordered_map>
#include <algorithm>
#include <set>
#include <iostream>
#include <chrono>
#include <cmath>
#include <map>
#define LN { std::cout << "LN " << __LINE__ << std::endl; }
using u64 = uint64_t;
using u128 = unsigned __int128;
static std::mt19937_64 rng{123}; //{std::random_device{}()};
auto CurTime() {
return std::chrono::high_resolution_clock::now();
}
static auto const gtb = CurTime();
double Time() {
return std::llround(std::chrono::duration_cast<
std::chrono::duration<double>>(CurTime() - gtb).count() * 1000) / 1000.0;
}
u64 PowMod(u64 a, u64 b, u64 const c) {
u64 r = 1;
while (b != 0) {
if (b & 1)
r = (u128(r) * a) % c;
a = (u128(a) * a) % c;
b >>= 1;
}
return r;
}
bool IsFermatPrp(u64 N, size_t ntrials = 24) {
// https://en.wikipedia.org/wiki/Fermat_primality_test
if (N <= 10)
return N == 2 || N == 3 || N == 5 || N == 7;
for (size_t trial = 0; trial < ntrials; ++trial)
if (PowMod(rng() % (N - 3) + 2, N - 1, N) != 1)
return false;
return true;
}
bool FactorTrialDivision(u64 N, std::vector<u64> & factors, u64 limit = u64(-1)) {
// https://en.wikipedia.org/wiki/Trial_division
if (N <= 1)
return true;
while ((N & 1) == 0) {
factors.push_back(2);
N >>= 1;
}
for (u64 d = 3; d <= limit && d * d <= N; d += 2)
while (N % d == 0) {
factors.push_back(d);
N /= d;
}
if (N > 1)
factors.push_back(N);
return N == 1;
}
u64 GCD(u64 a, u64 b) {
// https://en.wikipedia.org/wiki/Euclidean_algorithm
while (b != 0)
std::tie(a, b) = std::make_tuple(b, a % b);
return a;
}
bool FactorPollardRho(u64 N, std::vector<u64> & factors) {
// https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
auto f = [N](auto x) -> u64 { return (u128(x + 1) * (x + 1)) % N; };
auto DiffAbs = [](auto x, auto y){ return x >= y ? x - y : y - x; };
if (N <= 1)
return true;
if (IsFermatPrp(N)) {
factors.push_back(N);
return true;
}
for (size_t trial = 0; trial < 8; ++trial) {
u64 x = rng() % (N - 2) + 1;
size_t total_steps = 0;
for (size_t cycle = 1;; ++cycle) {
bool good = true;
u64 y = x;
for (u64 i = 0; i < (u64(1) << cycle); ++i) {
x = f(x);
++total_steps;
u64 const d = GCD(DiffAbs(x, y), N);
if (d > 1) {
if (d == N) {
good = false;
break;
}
//std::cout << N << ": " << d << ", " << total_steps << std::endl;
if (!FactorPollardRho(d, factors))
return false;
if (!FactorPollardRho(N / d, factors))
return false;
return true;
}
}
if (!good)
break;
}
}
factors.push_back(N);
return false;
}
void Factor(u64 N, std::vector<u64> & factors) {
if (N <= 1)
return;
if (1) {
FactorTrialDivision(N, factors, 1 << 8);
N = factors.back();
factors.pop_back();
}
FactorPollardRho(N, factors);
}
size_t SolveFactorize(std::vector<u64> const & nums) {
std::unordered_map<u64, size_t> cnts;
std::vector<u64> factors;
std::set<u64> unique_factors;
for (auto num: nums) {
factors.clear();
Factor(num, factors);
//std::cout << num << ": "; for (auto f: factors) std::cout << f << " "; std::cout << std::endl;
unique_factors.clear();
unique_factors.insert(factors.begin(), factors.end());
for (auto f: unique_factors)
++cnts[f];
}
size_t max_cnt = 0;
for (auto [_, cnt]: cnts)
max_cnt = std::max(max_cnt, cnt);
return max_cnt;
}
size_t SolveCommon(std::vector<u64> const & nums) {
size_t const K = nums.size();
std::set<u64> cmn(nums.begin(), nums.end()), cmn2, tcmn;
std::map<u64, bool> used;
cmn.erase(1);
while (true) {
cmn2.clear();
used.clear();
for (auto i = cmn.rbegin(); i != cmn.rend(); ++i) {
auto j = i;
++j;
for (; j != cmn.rend(); ++j) {
auto gcd = GCD(*i, *j);
if (gcd != 1) {
used[*i] = true;
used[*j] = true;
cmn2.insert(gcd);
cmn2.insert(*i / gcd);
cmn2.insert(*j / gcd);
break;
}
}
if (!used[*i])
tcmn.insert(*i);
}
cmn2.erase(1);
if (cmn2.empty())
break;
cmn = cmn2;
}
//for (auto c: cmn) std::cout << c << " "; std::cout << std::endl;
std::unordered_map<u64, size_t> cnts;
for (auto num: nums)
for (auto c: tcmn)
if (num % c == 0)
++cnts[c];
size_t max_cnt = 0;
for (auto [_, cnt]: cnts)
max_cnt = std::max(max_cnt, cnt);
return max_cnt;
}
void TestRandom() {
size_t const cnt_nums = 1000;
std::vector<u64> nums;
for (size_t i = 0; i < cnt_nums; ++i) {
nums.push_back((rng() & ((u64(1) << 20) - 1)) | 1);
//std::cout << nums.back() << " ";
}
//std::cout << std::endl;
{
auto tb = Time();
std::cout << "common " << SolveCommon(nums) << " time " << (Time() - tb) << std::endl;
}
{
auto tb = Time();
std::cout << "factorize " << SolveFactorize(nums) << " time " << (Time() - tb) << std::endl;
}
}
int main() {
TestRandom();
}
Output:
common 325 time 0.061
factorize 325 time 0.005
I think you need to search among all possible prime numbers to find out which prime number can divide most element in the array.
Code:
std::vector<int> primeLessEqualThanN(int N) {
std::vector<int> primes;
for (int x = 2; x <= N; ++x) {
bool isPrime = true;
for (auto& p : primes) {
if (x % p == 0) {
isPrime = false;
break;
}
}
if (isPrime) primes.push_back(x);
}
return primes;
}
int maxNumberGCDGreaterThan1(int N, std::vector<int>& A) {
int A_MAX = *std::max_element(A.begin(), A.end()); // largest number in A
std::vector<int> primes = primeLessEqualThanN(std::sqrt(A_MAX));
int max_count = 0;
for (auto& p : primes) {
int count = 0;
for (auto& n : A)
if (n % p == 0)
count++;
max_count = count > max_count ? count : max_count;
}
return max_count;
}
Note that in this way you cannot find out the value of the GCD, the code is based on that we dont need to know it.
Tribonacci numbers are defined as below. I am trying to write a program that checks if a number is a tribonacci number. I have wrote the function, but how can I acctually check if the number is a trib number with this? Because when I enter 45, it wont return anything.
T0=0
T1=1
T2=2
Tn=Tn-1 + Tn-2 + Tn-3 (for n>2)
int trib(int n)
{
if (n == 0 || n == 1 || n == 2)
{
cout << "YES";
}
if (n >= 2)
{
return trib(n - 1) + trib(n - 2) + trib(n - 3);
}
}
int main()
{
int input;
cin >> input;
cout << trib(input);
}
If input
3
45
then output
YES
NO
Other than memoization + recursion, an old style approach is to use a while loop and stop if the value >=n:
#include <iostream>
bool trib(int n)
{
if (n == 0 || n == 1 || n == 2) {return true;}
int a = 0, b = 1, c = 2, d = a+b+c;
while(d < n)
{
a = b; b = c; c = d; d = a+b+c;
}
if (d == n) {return true;} return false;
}
int main()
{
int input; std::cin >> input;
if (trib(input)) {std::cout << "YES";} else {std::cout << "NO";}
}
Result :
3 --> YES
11 --> YES
45 --> NO
Your implementation of recursion (without memoization) will have exponentially time complexity.
Edit: To the second question: I have to input number betwen 0<= && <= 1000000 So I need to make for loop to count 1000000 tribonacci numbers? This will take year.
Seriously? A good to average computers will loop from 1 -> 10^6 in less than 1 second.
Not mentioning that from 1 -> 10^6 based on your formula there's only... 23 Tribonacci number:
#include <iostream>
bool trib(int n)
{
if (n == 0 || n == 1 || n == 2) {return true;}
int a = 0, b = 1, c = 2, d = a+b+c;
while(d < n)
{
a = b; b = c; c = d; d = a+b+c;
}
if (d == n) {return true;} return false;
}
int main()
{
int counter = 0;
for (int i = 1; i <= 1000000; i++)
{
if (trib(i)) {std::cout << i << '\n'; counter++;}
}
std::cout << "Counter : " << counter;
}
Result:
1
2
3
6
11
20
37
68
125
230
423
778
1431
2632
4841
8904
16377
30122
55403
101902
187427
344732
634061
Counter : 23
There are several problems.
You need to understand that the values are growing strongly exponential. Already the 24th value will be greater then 1000000.
Then, your function does not work as specified. You also made a very slow implementation. But does not matter in this case.
But then, you made a wrong design. What you need to use is memoization. Sounds complicated, but is not. Simply precalculate the first 25 trib numbers, and the check, if the input is such a number.
Basically very simple. There are one million possible solutions. Here is a straightforward one based on your original approach:
constexpr size_t MaxNumbers = 25u;
int trib(int n)
{
if (n < 3) return n;
return trib(n - 1) + trib(n - 2) + trib(n - 3);
}
int main()
{
int tribNumber[MaxNumbers]{};
for (int i{}; i < MaxNumbers; ++i) {
tribNumber[i] = trib(i);
}
std::cout << "\nEnter number in the range 0...1'000'000: ";
unsigned int numberToCheck{};
if (std::cin >> numberToCheck and numberToCheck <= 1'000'000) {
bool found{};
for (int i{}; i < MaxNumbers; ++i) {
if (tribNumber[i] == numberToCheck) {
found = true;
}
}
if (found)
std::cout << "Yes\n";
else
std::cout << "No\n";
}
else {
std::cerr << "\nError: Wrong Input\n";
}
return 0;
}
By the way. All trib numbers can be easily calculated at runtime. This will make your program ultrafast and very compact. I cannot imagine a better solution.
#include <iostream>
#include <array>
#include <algorithm>
// Begin of all done during compile time -------------------------------------------------------------------
constexpr unsigned int getTribonacciNumber(size_t index) noexcept {
if (index < 3) return index;
unsigned int f0{ 0u }, f1{ 1ull }, f2{ 2ull }, f3{};
index -= 2;
while (index--) { f3 = f2 + f1 + f0; f0 = f1; f1 = f2; f2 = f3; }
return f2;
}
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices)... };
}
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
constexpr size_t MaxIndexForTribonacci = 25u;
// This is the definition of a std::array<unsigned int, 93> with all Tribonacci numbers in it
constexpr auto trib = generateArray<MaxIndexForTribonacci>(getTribonacciNumber);
// End of: All done during compile time -----------------------------------------------------------
// The only code executed during runtime
int main() {
// Show all Tribonacci numbers up to border value
for (const unsigned int t : trib) std::cout << t << '\n';
return 0;
}
See, everything is done during compile time. The resulting array is a compile time array. No calculation at all is done during runtime.
And if you want to addapt this program for your specific requiremens, then youcan use the below:
#include <iostream>
#include <array>
#include <algorithm>
// Begin of all done during compile time -------------------------------------------------------------------
constexpr unsigned int getTribonacciNumber(size_t index) noexcept {
if (index < 3) return index;
unsigned int f0{ 0u }, f1{ 1ull }, f2{ 2ull }, f3{};
index -= 2;
while (index--) { f3 = f2 + f1 + f0; f0 = f1; f1 = f2; f2 = f3; }
return f2;
}
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices)... };
}
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
constexpr size_t MaxIndexForTribonacci = 25u;
// This is the definition of a std::array<unsigned int, 93> with all Tribonacci numbers in it
constexpr auto trib = generateArray<MaxIndexForTribonacci>(getTribonacciNumber);
// End of: All done during compile time -----------------------------------------------------------
// The only code executed during runtime
int main() {
std::cout << "\nEnter number in the range 0...1'000'000: ";
unsigned int numberToCheck{};
if (std::cin >> numberToCheck and numberToCheck <= 1'000'000) {
if (binary_search(trib.begin(), trib.end(), numberToCheck))
std::cout << "Yes\n";
else
std::cout << "No\n";
}
else {
std::cerr << "\nError: Wrong Input\n";
}
return 0;
}
This approach will outperform nearly everything . . .
I think, without using recursion, the program might become a lot faster and easier. we will just see if input matches any of trib0,trib1,trib2.
tribonacci= 0, 0, 1, 1, 2, 4, 7, 13, 24, 44, 81, 149, 274, 504
trib(n)= 0 1 2 0 1 2 0 1 2 0 1 2 0 1
#include <iostream>
using namespace std ;
int main(int argc, char const *argv[])
{
int n;
cin>> n;
int trib0 = 0, trib1 = 0, trib2 = 1;
if (n == trib0 || n == trib1 || n == trib2)
{
cout<<"YES, it is tribonacci\n";
return 0;
}
while(trib0<=n)
{
trib0 = trib0 + trib1 + trib2;
if (n == trib0)
{
cout<<"YES, it is tribonacci\n";
return 0;
}
trib1 = trib0 + trib1 + trib2;
if ( n == trib1)
{
cout<<"YES, it is tribonacci\n";
return 0;
}
trib2 = trib0 + trib1 + trib2;
if (n == trib2)
{
cout<<"YES, it is tribonacci\n";
return 0;
}
}
cout<<"No, it's not\n";
return 0;
}
I'm trying to solve this problem:
Given three integers N, L, and R, find the integer M between L and R (inclusive) that maximizes M|N (the bitwise-OR of M and N). If there are multiple such values of M, return the least of them.
For example: N=100,L=50,R=60. The result is 59. Because 100|59 reaches the maximum value and 50<=59<=60.
This is my attempt:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
ll n,m,l,r,i,tmp,res,first,second,vt,dau,third=0,aka,check_high=0;
while(cin>>n>>l>>r){
tmp=0;dau=0;
for(i=31;i>=0;i--){
first = (l>>i)&1;
second = (r>>i)&1;
third = (n>>i)&1;
if(first==0&&second==0&&dau==0) continue;
dau=1;
if(first==1&&dau==1&&tmp==0) {tmp|=(1<<i);continue;}
if(first==0&&dau==1&&tmp==0) if(third==0) {tmp|=(1<<i);continue;}
if(first==0&&second==0&&third==0){
if(tmp|(1<<i)<=r) tmp|=(1<<i);
continue;
}
if(first==0&&second==1&&third==0){
if(tmp|(1<<i)<=r) tmp|=(1<<i);
continue;
}
if(first==1&&second==0&&third==0){
if(tmp|(1<<i)<=r) tmp|=(1<<i);
continue;
}
if(first==1&&second==1&&third==0){
if(tmp|(1<<i)<=r) tmp|=(1<<i);
continue;
}
}
cout<<tmp<<'\n';
}
return 0;
}
My idea is to browse each bit from left to right (it's mean form 31'st bit down to 0's bit) of L,R,N. Then, use the comparative statement to find the number M that satisfies the problem , specifically like above.
But when submit solution, I got Wrong Answer, this means, my algorithm is false, ans I'm stucking in ideal so solve this problem, can you help me this stuck ?
Without params validation
uint32_t getM(uint32_t L, uint32_t R, uint32_t N) {
auto M = L;
for (int bit = sizeof(L) * 8; bit > 0;) {
const decltype(L) value = 1 << (--bit);
if (value & N) {
if (value & M) {
decltype(L) check_value = M & (~value);
for (int i = bit; i > 0;) {
check_value |= (1 << (--i));
}
if (check_value >= L) {
M = check_value;
}
}
}
else {
if (!(value & M)) {
decltype(L) check_value = M | value;
for (int i = bit; i > 0;) {
check_value &= (~(1 << (--i)));
}
if (check_value <= R) {
M = check_value;
}
}
}
}
return M;
}
int main(int, char**)
{
std::cout << "M=" << getM(50, 60, 100) << std::endl;
std::cout << "M=" << getM(184, 270, 103) << std::endl;
return 0;
}
Output:
M=59
M=264
I'm trying to write an octal to decimal conversion app.
The problem is the return value is 1 less than it should be, ex.:
INPUT: 2426 (OCT)
SHOULD RETURN: 1302 (DEC)
RETURNS: 1301 (DEC)
Any ideas what's wrong? I'm using newest Code::Blocks if someone wants to know.
Here's my code:
int oct2dec (int number) {
int system = 8;
int length = IntegerLength(number);
int power = length - 1;
int result = 0;
int partial = 0;
do {
partial = part_nr(number);
cout<<"czastka: "<<partial<<endl;
result = result + (partial * pow(system,power));
number = number - (partial * pow(10,power));
power--;
} while (number>0);
return result;
}
part_nr function:
int part_nr(int number) {
int multipler = 1;
int result = 0;
do {
int temp=number/multipler;
if(temp<10) result = temp;
multipler = multipler*10;
} while (result == 0);
return result;
}
IntegerLength function:
int IntegerLength(int value) {
int divisor = 10;
int length = 1;
while(value >= divisor)
{
value = (value - (value % divisor)) / divisor;
length ++;
}
return length;
}
(btw. I've translated variables from my native lang to english, so if you see any non-eng variable say so, i'll correct it)
I'd think you just have problems with rounding in you algorithm. Anyway, this is not the way to do the conversion anyway: on the way in, you just read the digit and add it to the current value. If there is another digit, you multiply by 8 and reapeat.
On the way out, you take the remainder (modulus) of the division by 10 to form the next digit. Then you divide by 10 and while the result is non-zero you repeat.
You can do this much easier than what you are trying to. For example:
unsigned int oct2dec(unsigned int oct) {
int dec = 0, m = 1;
while (oct > 0) {
dec += m * (oct % 10);
oct /= 10;
m *= 8;
}
return dec;
}
I have tested your code and it is outputting the value you claim to be expected. The only problem I encountered was with rounding. I changed the pow() function call to powf(), and then I cast the result of that function to integer.
This is the code I tested (VS2010 C++ Project):
#include "stdafx.h"
#include <iostream>
#include <cmath>
using namespace std;
int part_nr(int number) {
int multipler = 1;
int result = 0;
do {
int temp=number/multipler;
if(temp<10) result = temp;
multipler = multipler*10;
} while (result == 0);
return result;
}
int IntegerLength(int value) {
int divisor = 10;
int length = 1;
while(value >= divisor)
{
value = (value - (value % divisor)) / divisor;
length++;
}
return length;
}
int oct2dec (int number) {
int system = 8;
int length = IntegerLength(number);
int power = length - 1;
int result = 0;
int partial = 0;
do {
partial = part_nr(number);
cout<<"czastka: "<<partial<< endl;
result = result + (partial * (int)powf(system,power));
number = number - (partial * (int)powf(10,power));
power--;
} while (number>0);
return result;
}
int _tmain(int argc, _TCHAR* argv[])
{
int res = oct2dec(2426);
cout << "res is " << res << endl;
getchar();
return 0;
}