簡體   English   中英

如何使用 C 中的循環找到滿足 (x - y * sqrt(2016.0)) / (y + sqrt(2016.0)) = 2016 的數字

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM