Вот решение. Вам не нужно 2 петли
public class App
{
public static void main( String[] args )
{
int arr[] = {3, 5, 7, 1};
System.out.println( go(arr) );
}
static int go(int[] array) {
int oddPos = -1;
for (int i = 0; i < array.length; i++) {
//check if already din't find an odd number and if current number is odd
if (oddPos == -1 && array[i] % 2 == 1) {
oddPos = i;
}
// check if already found an odd number and current number is even
if (oddPos != -1 && array[i] % 2 == 0) {
return i - oddPos;
}
}
return -1;
}
}
Delphi хранит промежуточные значения как расширенные (80-битный тип с плавающей запятой). Это выражение расширено:
i1*d1-Sqr(d2);
То же самое может не относиться к C # (я не знаю). Дополнительная точность может иметь значение.
Обратите внимание, что вы находитесь в пределах точности типа данных Double здесь, что означает, что вычисления здесь не будет точным.
Пример:
d1 = 4.271343859532459e+18
, который можно назвать таким же, как:
d1 = 4271343859532459000
и так:
d1 * i1 = 21356719297662295000
на самом деле, значение в .NET будет выглядеть примерно так:
2.1356719297662296E+19
Обратите внимание на округление там. Следовательно, на этом уровне вы не получаете правильных ответов.
Это, конечно, не объяснение этой точной ситуации, но это поможет объяснить проблему.
Что каждый ученый должен знать об арифметике с плавающей точкой
Любой такой расчет приведет к драме с типичной арифметикой с плавающей запятой. Чем больше разница в масштабировании чисел, тем выше вероятность возникновения проблемы с точностью.
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems дает хороший обзор.
AC # double имеет точность не более 16 цифр. Взяв 4.271343859532459e + 18 и умножив на 5, получим число из 19 цифр. Вы хотите иметь номер только с 3 цифрами в результате. Double не может этого сделать.
В C # тип Decimal может обработать этот пример - если вы знаете, что используете формат 123M для инициализации десятичных значений.
Decimal d1, d2, d3;
int i1;
d1 = 4.271343859532459e+18M;
d2 = 4621333065.0M;
i1 = 5;
d3 = (i1 * d1) - (d2*d2);
MessageBox.Show(d3.ToString());
Это дает 775.00, что является правильным ответом.
Я думаю, что это ошибка, вызванная ограниченной точностью (прежде всего потому, что вместо числа используются целые числа). Возможно, d1 не тот же, что и после назначения. d2 * d2, безусловно, будет отличаться от правильного значения, поскольку оно больше 2 ^ 32.
Поскольку 5 * d1 даже больше 2 ^ 64, даже использование 64-битных целых чисел не поможет. Вы должны будете использовать bignums или 128-битный целочисленный класс, чтобы получить правильный результат.
Как прокомментировали другие, двойное не достаточно точно для вашего вычисления. Десятичная дробь - хорошая альтернатива, хотя кто-то указал, что она будет округлена, но это не так.
В C # тип десятичной дроби не может легко обработать этот пример, так как 4.271343859532459e + 18 будет округлено до 4271343859532460000.
Это не тот случай. Ответ, если вы используете десятичную, будет правильным. Но, как он сказал, диапазон отличается.
По сути, как отмечали другие люди, двойной точности недостаточно для масштаба вычислений, которые вы пытаетесь выполнить. По умолчанию Delphi использует «расширенную точность», которая добавляет еще 16 бит по сравнению с Double, чтобы обеспечить более точные вычисления. .NET Framework не имеет типа данных с расширенной точностью.
Не уверен, какой тип использует ваш калькулятор, но он явно делает что-то отличное от Delphi и C #.