Почему эта небольшая С# -программа на SharpDevelop, которая использует циклы "для" не работает?

Я полный новичок. Я написал небольшую программу С# на SharpDevelop. Вот:

****** i, j;

for(i=1; i<=30; i+=(1/60))
{
 for(j=1+1/60; j<=30; j+=(1/60))
 {
 if(Math.Abs(Math.Log(i)/Math.Log(j)-0.63092975357)<=0.00001)
 {
 Console.WriteLine("ln("+i+") ln("+j+")");
 }
 }
}

 Console.ReadKey(true);

Моя программа должна найти i и j для которых ln(i)/ln(j)=0.63092975357 (например) i и j обязательно равны n/60 и m/60 соответственно, где n и m являются положительными целые числа. (Я знаю, что я могу использовать тип int вместо типа ******, но я хотел бы заставить его работать с типом ******.)

Но это не сработает. Когда я нажимаю "Run Project", появляется черный экран, но ничего не происходит... И SharpDevelop не указывает на какие-либо ошибки...

Какие ошибки я сделал? И как исправить мою программу?

4 ответа

Целочисленное разделение.

1/60 = 0

Вам нужно 1/60.0d вместо этого.

Когда вы делите на целое число, вы получите целочисленный результат. Целые числа не способны хранить десятичные знаки.

Когда вы делаете 1/60 вы ожидаете 0.0166666666666667 но это сообщение 0.

Этот код теперь работает

****** i, j;

for(i=1; i<=30; i+=(1/60d))
{
 for(j=1+1/60d; j<=30; j+=(1/60d))
 {
 if(Math.Abs(Math.Log(i)/Math.Log(j)-0.63092975357)<=0.00001) 
 Console.WriteLine("ln("+i+") ln("+j+")"); 
 }
}

EDIT: * Наверное, стоит упомянуть, что запись 60d гарантирует, что 60 является двойным типом. Следовательно, ваше подразделение теперь перенастраивает двойной *


Вы могли бы сделать свою жизнь немного легче, сохранив ваши циклы и целые числа, а затем выработав удвоения по мере необходимости, когда вам понадобятся функции журнала.

Также, добавляя Console.Write() перед ReadKey, вы можете видеть, когда цикл завершается.

for(var i=1; i<=1800; i++)
{
 for(var j=1; j<=1800; j++)
 {
 ****** di = ******(i)/60.0; 
 ****** dj = ******(j)/60.0;

 if(Math.Abs((Math.Log(di)/Math.Log(dj))-0.63092975357)<=0.00001)
 {
 Console.WriteLine("ln("+di+") ln("+dj+")");
 }
 }
}

Console.WriteLine("Press any key to continue");
Console.ReadKey(true);


Ошибка, которую я вижу здесь, использует 1/60, ожидая, что это будет двойное представление 0,0166... Это фактически 0, потому что и 1 и 60 являются целыми числами, и это становится целым делением. Попробуйте использовать 1.0/60.0, 1/60.0 или 1.0/60, 1/60d или любую их комбинацию, и это должно исправить ее, если ваш алгоритм математически корректен.

Как только вы исправите это, вы можете начать видеть большое количество строк, печатающих некоторые результаты, так как ваша программа не будет завершена до тех пор, пока циклы не закончатся, даже подумал, что она уже может печатать много данных. Вы можете исправить это, добавив переменную флага (bool), чтобы завершить внешний цикл и break чтобы завершить внутренний.


1/60 выполняет целочисленное деление и всегда генерирует 0. Он всегда отбрасывает дробную часть.

From / Operator (ссылка С#)

Когда вы делите два целых числа, результат всегда является целым числом. Например, результат 7/3 равен 2.

Вот почему ваш первый цикл будет похож на;

for(i = 1; i <= 30; i += 0)

так как i никогда не увеличился, ему никогда не будет 30 и поэтому это порождает бесконечный цикл.

В качестве решения вам нужно использовать деление с плавающей запятой.

for(i = 1; i <= 30; i += (1 / 60f))
{
 for(j = 1+1/60f; j <= 30; j += (1 / 60))

Кроме того, я предлагаю вам прочитать Eric Lippert. Как отлаживать небольшие программы, которые вы можете легко найти, что не так в вашем коде, даже не спрашивая здесь.

licensed under cc by-sa 3.0 with attribution.