#/*********************************************************** # cardano.c -- 3次方程式 #***********************************************************/ PI = 3.14159265358979323846264 # 円周率 $check = true def cuberoot( x ) # $\sqrtxend$ if (x == 0); return 0; end if (x > 0); pos = 1; else; pos = 0; x = -x; end if (x > 1); s = x; else; s = x; end begin prev = s; s = (x / (s * s) + 2 * s) / 3 end while (s < prev) if (pos); return prev; else; return -prev; end end def cardano( a, b, c, d ) # $ax^3 + bx^2 + cx + d = 0$, $a \ne 0$ b /= (3 * a); c /= a; d /= a p = b * b - c / 3 q = (b * (c - 2 * b * b) - d) / 2 a = q * q - p * p * p if (a == 0) q = cuberoot(q); x1 = 2 * q - b; x2 = -q - b printf("x = %g, %g (重解)\n", x1, x2) if ($check) printf("f(x1) = %g\n", x1 * (x1 * (x1 + 3 * b) + c) + d) printf("f(x2) = %g\n", x2 * (x2 * (x2 + 3 * b) + c) + d) end elsif (a > 0) if (q > 0); a3 = cuberoot(q + Math::sqrt(a)) else; a3 = cuberoot(q - Math::sqrt(a)) end b3 = p / a3 x1 = a3 + b3 - b; x2 = -0.5 * (a3 + b3) - b x3 = (a3 - b3).abs * Math::sqrt(3.0) / 2 printf("x = %g; %g +- %g i\n", x1, x2, x3) if ($check) printf("f(x1) = %g\n", x1 * (x1 * (x1 + 3 * b) + c) + d) printf("f(x2+-x3i) = %g +- %g i\n", ((x2+3*b)*x2-x3*x3+c)*x2-(2*x2+3*b)*x3*x3+d, ((3*x2+6*b)*x2-x3*x3+c)*x3) end else a = Math::sqrt(p); t = Math::acos(q / (p * a)); a *= 2 x1 = a * Math::cos( t / 3) - b x2 = a * Math::cos((t + 2 * PI) / 3) - b x3 = a * Math::cos((t + 4 * PI) / 3) - b printf("x = %g, %g, %g\n", x1, x2, x3) if ($check) printf("f(x2) = %g\n", x2 * (x2 * (x2 + 3 * b) + c) + d) printf("f(x3) = %g\n", x3 * (x3 * (x3 + 3 * b) + c) + d) end end end printf("a b c d = ") a, b, c, d = gets.split.collect {|data| data.to_f} if (a == 0) printf("3次方程式ではありません.\n") exit 1 end cardano(a, b, c, d) exit 0