| Thread Closed |
sneaky bug |
Share Thread | Thread Tools |
| Aug15-08, 11:43 PM | #1 |
|
|
sneaky bug
Hello. I wrote a simple program that helps me simplify radicals:
Code:
#include <iostream>
#include <math.h>
typedef struct
{
unsigned int x, y;
}pair;
bool breakcube(unsigned int radi, unsigned short inx, pair& pr)
{
unsigned int cb = 0;
for (unsigned int i = 2; i < radi; i++)
{
cb=i;
for (unsigned short j = 1; j < inx; j++)
cb*=i;
for (unsigned int j = 1; j < radi; j++)
{
if (cb*j==radi)
{
pr.x = cb;
pr.y = j;
return true;
}
}
}
return false;
}
int main()
{
unsigned int radi = 0;
unsigned int cb = 0;
unsigned short inx = 0;
char buff[64];
while(true)
{
std::cout << "\nEnter radicand ('quit' to terminate): ";
std::cin >> buff;
if (!strcmp(buff, "quit"))
return 0;
radi=(unsigned int)atof(buff);
std::cout << "\nEnter index: ";
std::cin >> inx;
cb = (unsigned int)pow(radi, 1.0/inx);
if ((double)pow(radi, 1.0/inx) == cb) // force the comparison
{
std::cout << "\nPerfect " << inx << " : ";
for (unsigned short i = 0; i < inx; i++)
{
std::cout << cb;
if (i!=inx-1)
std::cout << " * ";
}
std::cout << " = " << pow(cb, inx);
continue;
}
pair pr;
if (breakcube(radi, inx, pr))
std::cout << "\n" << radi << " can be broken by: " << pr.x << " * " << pr.y;
else
std::cout << "\n" << radi << " cannot be broken";
}
return 0;
}
|
| Aug16-08, 11:07 AM | #2 |
|
Recognitions:
|
I'm having a bit of trouble following the code, but you can check if a number is a cube with
Code:
bool isCube(int n, int& root) {
root = (int)(0.5 + pow(n, 1.0/3)); // Nearest integer to the cube root
return root * root * root == n;
}
Code:
void simplify (int radicand, int& factor) {
factor = 1;
// Check for factors of 2; replace operations with shifts for better speed.
while (radicand%4 == 0) {
radicand /= 4;
factor *= 2;
}
// Check for odd factors
int limit = (int)(sqrt(radicand) + .0001); // Add small constant to avoid rounding the wrong way on perfect squares
for (int n = 3; n <= limit; n += 2) {
if (radicand % (n*n) == 0) {
radicand /= n * n;
factor *= n;
limit = (int)(sqrt(radicand) + .0001);
}
}
}
Of course using a list of primes could speed things along as well. |
| Aug16-08, 11:26 AM | #3 |
|
|
A quick look over it makes me think you're having rounding/casting issues.
Code:
cb = (unsigned int)pow(radi, 1.0/inx); if ((double)pow(radi, 1.0/inx) == cb) // force the comparison Try looking at the round() function, or maybe rethink how you're doing your check. Hope that helps. |
| Aug16-08, 03:29 PM | #4 |
|
|
sneaky bug
Thanks for the replies guys. CRGreathouse, the program helps break down radicals of any index, so explicitly checking for a cube root is not going to work here. The problem is, I have tried stepping through the code using a debugger, string outputs, rounding, pretty much everything I can think off, everything should work as expected, but it doesn't. Bill_B, if it was some rounding problem, wouldn't it present itself for other indexes too? For simplicity's sakes, here's the problem demonstrated in python:
Code:
#! /usr/bin/python
iRad = int(raw_input("Enter cube: "))
fR = pow(iRad, 1.0/3)
if fR == int(fR):
print str(iRad) + " is a cube"
else:
print str(iRad) + " is not a cube"
|
| Aug16-08, 03:57 PM | #5 |
|
|
When I execute the program with an input of 64,3 - after this line - Code:
cb = (unsigned int)pow(radi, 1.0/inx); So when this line is executed - Code:
if ((double)pow(radi, 1.0/inx) == cb) // force the comparison I still stand by my original answer. |
| Aug16-08, 05:15 PM | #6 |
|
Recognitions:
|
Code:
int simplify (int radicand, int idx) {
int factor = 1;
// Check for factors of 2; replace operations with shifts for better speed.
while (radicand%pow(2, idx) == 0) {
radicand /= pow(2, idx);
factor *= 2;
}
// Check for odd factors
int limit = (int)(pow(radicand, 1.0/idx) + .0001); // Add small constant to avoid rounding the wrong way on perfect powers
for (int n = 3; n <= limit; n += 2) {
while (radicand % pow(n, idx) == 0) {
radicand /= pow(n, idx);
factor *= n;
limit = (int)(pow(radicand, 1.0/idx) + .0001);
}
}
return factor;
}
Code:
int pow(int a, int b) {
int c = 1;
while (b > 1) {
if (b&1)
c *= a;
a *= a;
b >>= 1;
}
return c * a;
}
|
| Aug16-08, 11:12 PM | #7 |
|
|
Thanks for that. I am not accomplished at mathematical algorithms, so don't expect any good code coming from me. :)
|
| Aug17-08, 01:08 PM | #8 |
|
|
Here's the final program, in working condition. It might not be the fastest, but it helps nonetheless. CRGreathouse, your suggestions were great, but a bit over my head buddy. Bill_B, thank you as well.
EDIT: Nope, false alarm. :( It certainly is better, it now recognizes 64 as a perfect cube, but it doesn't recognize 125...I am gloomy now. Code:
#include <iostream>
#include <math.h>
typedef struct
{
unsigned int x, y;
}pair;
bool breakcube(unsigned int radi, unsigned short inx, pair& pr)
{
unsigned int cb = 0;
for (unsigned int i = 2; i < radi; i++)
{
cb=i;
for (unsigned short j = 1; j < inx; j++)
cb*=i;
for (unsigned int j = 1; j < radi; j++)
{
if (cb*j==radi)
{
pr.x = cb;
pr.y = j;
return true;
}
}
}
return false;
}
bool isPerfect(int rad, int idx)
{
double rt = pow(rad, 1.0/idx);
rt = round(rt);
if (pow(rt, idx)==rad)
return true;
return false;
}
int main()
{
unsigned int radi = 0;
double cb = 0;
unsigned short inx = 0;
char buff[64];
while(true)
{
std::cout << "\nEnter radicand ('quit' to terminate): ";
std::cin >> buff;
if (!strcmp(buff, "quit"))
return 0;
radi=(unsigned int)atof(buff);
std::cout << "\nEnter index: ";
std::cin >> inx;
cb = pow(radi, 1.0/inx);
if (isPerfect(radi, inx))
{
std::cout << "\nPerfect " << inx << " : ";
for (unsigned short i = 0; i < inx; i++)
{
std::cout << cb;
if (i!=inx-1)
std::cout << " * ";
}
std::cout << " = " << pow(cb, inx);
continue;
}
pair pr;
if (breakcube(radi, inx, pr))
std::cout << "\n" << radi << " can be broken by: " << pr.x << " * " << pr.y;
else
std::cout << "\n" << radi << " cannot be broken";
}
return 0;
}
|
| Aug17-08, 06:39 PM | #9 |
|
Recognitions:
|
Code:
bool isPerfect(int rad, int idx)
{
double rt = pow(rad, 1.0/idx);
rt = round(rt);
if (pow(rt, idx)==rad)
return true;
return false;
}
|
| Aug18-08, 02:12 AM | #10 |
|
|
Ah!
![]() This seems to fix the problem! Code:
bool isPerfect(int rad, int idx)
{
double rt = pow(rad, 1.0/idx);
rt = round(rt);
if (round(pow(rt, idx))==rad)
return true;
return false;
}
|
| Aug18-08, 10:07 AM | #11 |
|
Recognitions:
|
|
| Thread Closed |
| Thread Tools | |
Similar Threads for: sneaky bug
|
||||
| Thread | Forum | Replies | ||
| Darn those cops can be sneaky | General Discussion | 15 | ||
| you sneaky damn jeweler | General Discussion | 11 | ||
| Evo is sneaky | General Discussion | 4 | ||