Цель C: Создание длинного двойного использования десятичного метода
-
14-10-2019 - |
Вопрос
Как создать следующий метод?
- Я попытался использовать MODF (N, 1) или MODF (N, 2), но оба возвращают ошибку «прохождение аргумента 2 MODF, что делает указатель из целого числа без состава.
Вот метод:
(BOOL) numberHasDecimal: (long double) n {
if (?????) // has decimal, like 16.300000 or 6453.353259
return YES;
else
return NO; // has no decimal, like 58.000000 or 9274.000000
}
Решение
if (fabsl(fmodl(n, 1.0)) > 0.0) {
// Has a decimal.
} else {
// Is an integer.
}
Имейте в виду, что значения с плавающей запятой внутренне округлены нелогичными способами, поэтому число может иметь очень маленький дробный компонент и все еще выглядеть неотъемлемой частью при прохождении через fmodl()
.
Также обратите внимание, что реализация Apple Objective-C нарушается при обработке long double
Значения и могут проявить трудные ошибки, когда вы их используете.
Другие советы
Другой выбор, не знаю, из чего выбирать, но, вероятно, не этот.
-(BOOL) numberHasDecimal: (long double) n {
NSMutableString *decimalTempString;
decimalTempString = [NSMutableString stringWithFormat: @"%Lf", n];
// while last character of string = 0 delete last character (1232.10000)
while ([decimalTempString characterAtIndex:([decimalTempString length] -1)] == '0') {
NSRange range = {([decimalTempString length] -1), 1};
[decimalTempString deleteCharactersInRange:range];
}
// if last character is . then delete that too (1232.)
if ([decimalTempString characterAtIndex:([decimalTempString length] -1)] == '.') {
return NO; // has no decimal, like 58. or 9274.
} else {
return YES; // has decimal, like 16.3 or 6453.353259
}
Как указали другие плакаты, лучший вопрос может заключаться в том, чтобы определить, что означает «не иметь десятичной части». (Кроме того, я повторяю их предостережение о длинных удвоениях.) Какое определение правильное, зависит от того, чего вы пытаетесь достичь. Я считаю, что «в 1E-6» часто является хорошим определением, но это зависит от ситуации.
Для вашего конкретного вопроса, вы, вероятно, хотите это:
-(BOOL) numberHasDecimal: (double) n
{
double integerPart = 0.;
if (fabs(modf(n, &integerPart)) > 0.) // has decimal, like 16.300000 or 6453.353259
return YES;
else
return NO; // has no decimal, like 58.000000 or 9274.000000
}
Что происходит, так это то, что функция MODF хочет вернуть дробную часть и хранить целочисленную часть номера в другой двойник, адрес которого вы передаете в нее. Несмотря на свое название, это не эквивалент «x % y»; Это действительно больше эквивалент «return x % 1.0, также хранение (x - пол (x)) в предоставленный указатель» (по крайней мере для положительных чисел, то есть.)
Вы можете подумать о втором параметре указателя как о способе вернуть более одного значения из одного вызова функции. Несмотря на то, что в этом случае вам все равно, что касается целочисленной части, передат адрес MODF, чтобы написать целочисленную часть, успокоит компилятор и получить вам результат, который вы ищете.
- (BOOL) numberHasDecimal:(long double)l {
return (floorl(l) != l);
}