const NFRule* NFRuleSet::findDoubleRule(double number) const { // if this is a fraction rule set, use findFractionRuleSetRule() if (isFractionRuleSet()) { return findFractionRuleSetRule(number); } if (uprv_isNaN(number)) { const NFRule *rule = nonNumericalRules[NAN_RULE_INDEX]; if (!rule) { rule = owner->getDefaultNaNRule(); } return rule; } // if the number is negative, return the negative number rule // (if there isn't a negative-number rule, we pretend it's a // positive number) if (number < 0) { if (nonNumericalRules[NEGATIVE_RULE_INDEX]) { return nonNumericalRules[NEGATIVE_RULE_INDEX]; } else { number = -number; } } if (uprv_isInfinite(number)) { const NFRule *rule = nonNumericalRules[INFINITY_RULE_INDEX]; if (!rule) { rule = owner->getDefaultInfinityRule(); } return rule; } // if the number isn't an integer, we use one of the fraction rules... if (number != uprv_floor(number)) { // if the number is between 0 and 1, return the proper // fraction rule if (number < 1 && nonNumericalRules[PROPER_FRACTION_RULE_INDEX]) { return nonNumericalRules[PROPER_FRACTION_RULE_INDEX]; } // otherwise, return the improper fraction rule else if (nonNumericalRules[IMPROPER_FRACTION_RULE_INDEX]) { return nonNumericalRules[IMPROPER_FRACTION_RULE_INDEX]; } } // if there's a master rule, use it to format the number if (nonNumericalRules[MASTER_RULE_INDEX]) { return nonNumericalRules[MASTER_RULE_INDEX]; } // and if we haven't yet returned a rule, use findNormalRule() // to find the applicable rule int64_t r = util64_fromDouble(number + 0.5); return findNormalRule(r); }
NFRule * NFRuleSet::findDoubleRule(double number) const { // if this is a fraction rule set, use findFractionRuleSetRule() if (isFractionRuleSet()) { return findFractionRuleSetRule(number); } // if the number is negative, return the negative number rule // (if there isn't a negative-number rule, we pretend it's a // positive number) if (number < 0) { if (negativeNumberRule) { return negativeNumberRule; } else { number = -number; } } // if the number isn't an integer, we use one of the fraction rules... if (number != uprv_floor(number)) { // if the number is between 0 and 1, return the proper // fraction rule if (number < 1 && fractionRules[1]) { return fractionRules[1]; } // otherwise, return the improper fraction rule else if (fractionRules[0]) { return fractionRules[0]; } } // if there's a master rule, use it to format the number if (fractionRules[2]) { return fractionRules[2]; } // and if we haven't yet returned a rule, use findNormalRule() // to find the applicable rule int64_t r = util64_fromDouble(number + 0.5); return findNormalRule(r); }
NFRule * NFRuleSet::findNormalRule(int64_t number) const { // if this is a fraction rule set, use findFractionRuleSetRule() // to find the rule (we should only go into this clause if the // value is 0) if (fIsFractionRuleSet) { return findFractionRuleSetRule((double)number); } // if the number is negative, return the negative-number rule // (if there isn't one, pretend the number is positive) if (number < 0) { if (negativeNumberRule) { return negativeNumberRule; } else { number = -number; } } // we have to repeat the preceding two checks, even though we // do them in findRule(), because the version of format() that // takes a long bypasses findRule() and goes straight to this // function. This function does skip the fraction rules since // we know the value is an integer (it also skips the master // rule, since it's considered a fraction rule. Skipping the // master rule in this function is also how we avoid infinite // recursion) // {dlf} unfortunately this fails if there are no rules except // special rules. If there are no rules, use the master rule. // binary-search the rule list for the applicable rule // (a rule is used for all values from its base value to // the next rule's base value) int32_t hi = rules.size(); if (hi > 0) { int32_t lo = 0; while (lo < hi) { int32_t mid = (lo + hi) / 2; if (rules[mid]->getBaseValue() == number) { return rules[mid]; } else if (rules[mid]->getBaseValue() > number) { hi = mid; } else { lo = mid + 1; } } if (hi == 0) { // bad rule set, minimum base > 0 return NULL; // want to throw exception here } NFRule *result = rules[hi - 1]; // use shouldRollBack() to see whether we need to invoke the // rollback rule (see shouldRollBack()'s documentation for // an explanation of the rollback rule). If we do, roll back // one rule and return that one instead of the one we'd normally // return if (result->shouldRollBack((double)number)) { if (hi == 1) { // bad rule set, no prior rule to rollback to from this base return NULL; } result = rules[hi - 2]; } return result; } // else use the master rule return fractionRules[2]; }