[英]How to find the numbers that satisfy (x - y * sqrt(2016.0)) / (y + sqrt(2016.0)) = 2016 using loops in C
我試圖找到滿足子句 (x - y * √ 2016) / (y + √ 2016) = 2016 的數字。數字 x 和 y 可以是有理數。
這就是我已經嘗試過的:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int x, y;
for(x = 1; x < 10000; x++) {
for(y = 1; y < 10000; y++) {
if( (x - y * sqrt(2016.0)) / (y + sqrt(2016.0) ) == 2016) {
printf("Numbers are: %d and %d.", x, y);
}
}
}
return 0;
}
使用浮點數學和蠻力搜索來“解決”這個問題在概念上是一個壞主意。 這是因為使用 FP 數學舍入誤差以非直觀方式傳播,因此許多在數學意義上可解的方程沒有(精確的)FP 數解。 因此,使用 FP 數學來逼近數學方程的解本身就很困難。
我建議在編程之前簡化問題。
如果這樣做並且只搜索整數解,你會發現唯一的解是
x = -2016^2 = -4064256
y = -2016
為什么:只需重新排列一下即可獲得
x = 2016*y + (2016 + y)*sqrt(2016)
由於 sqrt(2016) 不是整數,因此 sqrt 之前的子句中的項必須為零。 其他一切都由此而來。
如果需要非整數解,可以使用上述方法為每個 y 找到 x。 其中甚至列舉了所有解決方案。
因此,這表明在計算機中嘗試解決之前簡化數學問題通常是強制性的(尤其是 FP 數學)。
編輯:如果您尋找有理數,可以應用與整數情況相同的參數。 由於 sqrt(2016) 不是有理數,因此 y 也必須是 -2016。 因此,對於有理情況,唯一的解決方案與整數相同,即,
x = -2016^2 = -4064256
y = -2016
這只是一條線的方程。 這是一個確切的解決方案:
x = (sqrt(2016) + 2016)*y + 2016*sqrt(2016)
對於任何 y 值,x 由上述給出。 x 截距為:
x = 2016*sqrt(2016)
y = 0
y 軸截距為:
x = 0
y = -2016*sqrt(2016)/(sqrt(2016)+2016)
浮點運算的結果通常不准確。 改變:
if( (x - y * sqrt(2016.0)) / (y + sqrt(2016.0) ) == 2016)
像
if( fabs((x - y * sqrt(2016.0)) / (y + sqrt(2016.0) ) - 2016) < 0.00000001)
其中0.00000001
是您選擇的容差。
但正如所指出的,您不想搜索不必要的變量域。 先解決數學問題。 像這樣使用 Wolfram Alpha 我們得到 y=(x-24192*√14)/(12*(168+√14))
滿足 (x - y * sqrt(2016.0)) / (y + sqrt(2016.0)) = 2016 的數字
從@Tom Karzes開始
x = (sqrt(2016) + 2016)*y + 2016*sqrt(2016)
讓 y = -2016
x = (sqrt(2016) + 2016)*-2016 + 2016*sqrt(2016)
x = 2016*-2016 = -4064256
所以 x,y = -4064256, -2016是一種精確解。
對於數學,這是唯一的。
由於sqrt(x)
不完全是 √x 和double
數學的特性,可能還有其他解決方案可以通過 C 代碼模擬。
作為像 OP 一樣的 C 模擬,讓我們“猜測”答案的x,y
都是 2016 年的倍數,可能是負數。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double f(int x, int y) {
double z = (x - y * sqrt(2016.0)) / (y + sqrt(2016.0));
z = z - 2016;
return z * z;
}
#define M 3000
int main() {
double best_diff = DBL_MAX;
int best_x = 0;
int best_y = 0;
int x, y;
for (x = -M; x < M; x++) {
for (y = -M; y < M; y++) {
double diff = f(x * 2016, y * 2016);
if (diff < best_diff) {
best_diff = diff;
best_x = x;
best_y = y;
}
if (diff == 0) {
printf("Numbers are: %d and %d.\n", best_x*2016, best_y*2016);
}
}
}
if (best_diff != 0.0) {
printf("Numbers are: %d and %d --> %e.", best_x*2016, best_y*2016, best_diff);
}
return 0;
}
輸出
Numbers are: -4064256 and -2016.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.