I am trying to find all numbers with an integer cube root, but it hasn’t worked because appareantly cbrt() isn’t a processing supported function. how do I do this?
this is my code:
int x= 1;
if(cbrt(x)==int(cbrt(x)){
println(x);
}
else{
x++;
}
I am trying to find all numbers with an integer cube root, but it hasn’t worked because appareantly cbrt() isn’t a processing supported function. how do I do this?
this is my code:
int x= 1;
if(cbrt(x)==int(cbrt(x)){
println(x);
}
else{
x++;
}
You can have a look at this wikipedia article: nth root - Wikipedia
Indeed Processing devs think cbrt() usage is so rare it wasn’t worth to be included in Processing’s API.
However Java got that cbrt() function in its Math class; but it returns a double
instead of a float
value:
docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Math.html#cbrt(double)
We can also use pow() passing 1/3.
as its 2nd argument in order to emulate cbrt(): pow(x, 1/3.)
println(Math.cbrt(27) == pow(27, 1/3.)); // true
does pow also work for negative numbers?
Click at the pow()'s reference link I’ve posted and you’ll see examples w/ negative values as well.
I did but this code print NaN
int x= -1;
void draw() {
if (pow(x, 1/3.)==int(pow(x, 1/3.))) {
//println(x);
}
x=x-1;
println(pow(x, 1/3.));
}
for (int x = 1; x < 100; x++) {
if (Math.cbrt(x) == (int)Math.cbrt(x))
println(x);
}
Gives the result
1
8
27
64
which is what you are looking for
That’s a shortcoming of using pow() w/ negative bases & fractional exponents.
If you don’t wanna use Java’s own Math.cbrt() (maybe b/c you prefer your code to also run online via Pjs) and choose to stick w/ Processing’s pow() you can make your own cbrt() using pow():
// https://Discourse.Processing.org/t/how-do-i-calculate-the-cube-root/33988/8
// GoToLoop (2021/Dec/07)
import java.util.Map;
final Map<Integer, Integer> roots = new HashMap<Integer, Integer>();
static final int MIN_BASE = -125, MAX_BASE = 125;
void setup() {
for (int i = MIN_BASE; i <= MAX_BASE; ++i) {
final float root = cbrt(i), rootThreeDecimals = round(root * 1e3) / 1e3;
final int roundedRoot = round(root);
if (rootThreeDecimals == roundedRoot) roots.put(i, roundedRoot);
}
println(roots);
println(roots.size()); // 11
exit();
}
static final float cbrt(final float n) {
return n < 0? -pow(-n, 1/3.) : pow(n, 1/3.);
}
If you want to want to calculate the cube root of a real number using only the 4 basic math operators, (+ - * /) then you might try this out - it works
float a3 = -1.25*-1.25*-1.25;
float b3 = 1234*1234*1234;
float[] f = { 125, -64, a3, b3};
void setup() {
for (float n : f)
calculateAndDislay(n);
}
void calculateAndDislay(float x) {
print("Cube root of " + x + " is ");
println((float) cbrt(x));
}
// Use Halley's method to find the cube root of a real number
double cbrt(double x) {
if(x == 0) return 0;
double epsilon = 1e-6;
double r0 = x / 3;
double r, diff;
do {
double rc = r0 * r0 * r0;
r = r0 * (rc + 2 * x) / (2 * rc + x);
diff = r - r0;
r0 = r;
} while (diff < -epsilon || diff > epsilon);
return r;
}
thank you, I have another question, how do I make it only print the numbers if they are not infinitly repeating?
int x= -1;
void draw(){
float y=pow(x, 1.5);
if (Math.cbrt(x) == (int)Math.cbrt(x)){
println(x);
}
x=x-1;
}
There are an infinite number of numbers that have an integer cube root, so we cannot find all of them. But to calculate a number that has an integer cube root, all you need to do is cube an integer. Accordingly, to find the first n
numbers that have an integer cube root, just cube the first n
integers. There’s no need to actually calculate any cube roots to do this.
Following is a Python program that displays the first 11
numbers that have an integer cube root, along with their cube roots:
for cube_root in range(11):
print("{:4d} {:4d}".format(cube_root ** 3, cube_root))
Output:
0 0
1 1
8 2
27 3
64 4
125 5
216 6
343 7
512 8
729 9
1000 10
In the above, we did not need to calculate any cube roots.
On the other hand, if you wish to write a function that, given a number, calculates its cube root, one algorithm to consider is Newton’s method.
See the following:
The following Python function, written for Python 3, and decidedly not for Python 2, uses Newton’s method to calculate a cube root:
def cube_root(n):
# uses Newton's method
n = float(n)
# estimate the cube root
est = n / 2
prev_diff = max(n, 1)
while True:
# assign new_est the average of est and n / est * est
new_est = (est + n / (est * est)) / 2
# check how much the estimate has changed
curr_diff = abs(est - new_est)
# if the change has stopped decreasing, break and return the result
if curr_diff >= prev_diff:
break
# otherwise keep refining the estimate
prev_diff = curr_diff
est = new_est
return new_est
print(cube_root(1311494070536))
Output:
10946.0
That statement is definitely wrong b/c your posted code can be pasted and successfully run in Processing’s Python Mode (Jython), which is based on Python 2.
Also I’ve taken the opportunity to convert your cube root algorithm to Processing’s Java Mode:
void setup() {
println(cbrt(-1311494070536L)); // -10946.0
exit();
}
static final float cbrt(final float n) {
//return n < 0? -pow(-n, 1/3.) : pow(n, 1/3.);
if (n == 0) return 0;
final float v = abs(n), sign = n > 0? 1 : -1;
float est = v * .5, prevDiff = max(v, 1);
while (true) {
final float newEst = (v / sq(est) + est) * .5, currDiff = abs(est - newEst);
if (currDiff >= prevDiff) return newEst * sign;
est = newEst;
prevDiff = currDiff;
}
}
I should have stated, instead, that I have tested it quite a bit with Python 3, but have not tested it much on very large numbers with Python 2.
If you are going to use numerical methods to calculate the cube root then I suggest you use Halley’s method rather than Newton’s method as it converges on the answer more quickly and is just as easy to implement.
@javagar The Python method does not calculate the cube root of negative numbers correctly for instance cube_root(-125)
returns -31.266
rather than the correct answer of -5
. The problem is in the terminating condition of the while loop. You should not compare the differences between 2 iterations rather compare the answer from 2 successive iterations and see it it is less than some small value.
@GoToLoop 's Java conversion of your code corrects the issue of negative roots by getting the sign of the number to be cube rooted but this can also be avoided by comparing successive estimates rather than successive differences.