7

I defined the cbrt function to return a cube root. I need to get an integer back (even if it is close to the cube root, it will be acceptable in my case). However, when I put the scale as 0 to get an integer, I get numbers which are grossly incorrect. What is going on and how do I get an integer cube root out?

bc -l
define cbrt(x) { return e(l(x)/3) }
scale=1;cbrt(1000000)
99.4
scale=0;cbrt(1000000)
54
  • 1
    The docs says: "Every expression has a scale. This is derived from the scale of original numbers, the operation performed and in many cases, the value of the variable scale. ... expr / expr ... The scale of the result is the value of the variable scale." So, one easy way to make scale take effect is divide by 1. – x-yuri Dec 05 '18 at 16:51

1 Answers1

5

Setting scale before calling cbrt() has the effect of setting the scale whilst cbrt() is evaluated. The way around it is to stash the scale as part of the function:

define cbrt(x) { auto z, var; z=scale; scale=5; var = e(l(x)/3); scale=z; return (var); }

which when called gives:

scale=0; cbrt(1000000)
99.99998

Which seems to ignore that scale=0. This is because it evaluates cbrt() which temporarily sets the scale to 5 and calculates your cube root (to 5 floating points), assigns that to z and returns that value (which implicitly has scale set to 5). You can then apply the local scale=0 by simply dividing by 1:

scale=0; cbrt(100000)/1
99
Drav Sloan
  • 14,345
  • 4
  • 45
  • 43
  • 1
    I was able to get it to work with my original cbrt() by doing: "x=cbrt(1000000);scale=0;x/1". Which is essentially the same as what you are doing. Thanks. – FirstName LastName Aug 20 '13 at 19:57
  • Why did you have to declare the variables before using them? You could have omitted the first command and directly used the variables. – FirstName LastName Aug 20 '13 at 20:00
  • Which is far less long winded :) You can still use the x=scale trick if you do need to stash the existing scale I guess :) – Drav Sloan Aug 20 '13 at 20:00
  • 1
    Localization of the variables, if z or var are used outside of cbrt() they would get overwritten without the use of auto. – Drav Sloan Aug 20 '13 at 20:02