예제 #1
0
파일: safe_num.cpp 프로젝트: Andiry/mongo
bool SafeNum::isEquivalent(const SafeNum& rhs) const {
    if (!isValid() && !rhs.isValid()) {
        return true;
    }

    // EOO is not equivalent to anything else.
    if (!isValid() || !rhs.isValid()) {
        return false;
    }

    // If the types of either side are mixed, we'll try to find the shortest type we
    // can upconvert to that would not sacrifice the accuracy in the process.

    // If none of the sides is a double, compare them as long's.
    if (_type != NumberDouble && rhs._type != NumberDouble) {
        return getLongLong(*this) == getLongLong(rhs);
    }

    // If both sides are doubles, compare them as so.
    if (_type == NumberDouble && rhs._type == NumberDouble) {
        return _value.doubleVal == rhs._value.doubleVal;
    }

    // If we're mixing integers and doubles, we should be careful. Some integers are
    // too big to be accuratelly represented in a double. If we're within a safe range
    // we compare both sides as doubles.
    const double lhsDouble = getDouble(*this);
    const double rhsDouble = getDouble(rhs);
    if (lhsDouble > -maxIntInDouble && lhsDouble < maxIntInDouble && rhsDouble > -maxIntInDouble &&
        rhsDouble < maxIntInDouble) {
        return lhsDouble == rhsDouble;
    }

    return false;
}
예제 #2
0
파일: bit_node.cpp 프로젝트: DINKIN/mongo
SafeNum BitNode::applyOpList(SafeNum value) const {
    for (const auto& op : _opList) {
        value = (value.*(op.bitOperator))(op.operand);

        if (!value.isValid()) {
            uasserted(ErrorCodes::BadValue,
                      str::stream() << "Failed to apply $bit operations to current value: "
                                    << value.debugString());
        }
    }

    return value;
}