Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  Int96.h

  Sprache: C
 

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef builtin_temporal_Int96_h
#define builtin_temporal_Int96_h

#include "mozilla/Assertions.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Maybe.h"

#include <array>
#include <climits>
#include <stddef.h>
#include <stdint.h>
#include <utility>

namespace js::temporal {

/**
 * 96-bit integer with explicit sign. Supports integers in the range
 * [-(2**96 - 1), 2**96 - 1].
 */

class Int96 final {
 public:
  using Digit = uint32_t;
  using TwoDigit = uint64_t;

  // The 96-bit integer is stored as three separate 32-bit integers.
  using Digits = std::array<Digit, 3>;

 private:
  // Unsigned number in the range [0, 0xffff'ffff'ffff'ffff'ffff'ffff].
  //
  // The least significant digit is stored at index 0. The most significant
  // digit is stored at index 2.
  Digits digits = {};

  // Explicit negative sign.
  bool negative = false;

 public:
  // Default constructor initializes to zero.
  constexpr Int96() = default;

  // Create from an 64-bit integer.
  constexpr explicit Int96(int64_t value) : negative(value < 0) {
    // NB: Not std::abs, because std::abs(INT64_MIN) is undefined behavior.
    uint64_t abs = mozilla::Abs(value);
    digits[1] = uint32_t(abs >> 32);
    digits[0] = uint32_t(abs);
  }

  constexpr Int96(Digits digits, bool negative)
      : digits(digits), negative(negative) {
    // Assert zero is non-negative.
    MOZ_ASSERT_IF((digits[0] | digits[1] | digits[2]) == 0, !negative);
  }

  constexpr bool operator==(const Int96& other) const {
    return digits[0] == other.digits[0] && digits[1] == other.digits[1] &&
           digits[2] == other.digits[2] && negative == other.negative;
  }

  constexpr bool operator<(const Int96& other) const {
    if (negative != other.negative) {
      return negative;
    }
    for (size_t i = digits.size(); i != 0; --i) {
      Digit x = digits[i - 1];
      Digit y = other.digits[i - 1];
      if (x != y) {
        return negative ? x > y : x < y;
      }
    }
    return false;
  }

  // Other operators are implemented in terms of operator== and operator<.
  constexpr bool operator!=(const Int96& other) const {
    return !(*this == other);
  }
  constexpr bool operator>(const Int96& other) const { return other < *this; }
  constexpr bool operator<=(const Int96& other) const {
    return !(other < *this);
  }
  constexpr bool operator>=(const Int96& other) const {
    return !(*this < other);
  }

  /**
   * Multiply this integer with an multiplier. Overflow is not supported.
   */

  constexpr Int96& operator*=(Digit multiplier) {
    Digit carry = 0;
    for (auto& digit : digits) {
      TwoDigit d = digit;
      d *= multiplier;
      d += carry;

      digit = Digit(d);
      carry = Digit(d >> 32);
    }
    MOZ_ASSERT(carry == 0"unsupported overflow");

    return *this;
  }

  /**
   * Multiply this integer with an multiplier. Overflow is not supported.
   */

  constexpr Int96 operator*(Digit multiplier) const {
    auto result = *this;
    result *= multiplier;
    return result;
  }

  /**
   * Divide this integer by the divisor using Euclidean division. The divisor
   * must be smaller than the most significant digit of the integer. Returns the
   * quotient and the remainder.
   */

  constexpr std::pair<int64_t, int32_t> operator/(Digit divisor) const {
    MOZ_ASSERT(digits[2] < divisor, "unsupported divisor");

    Digit quotient[2] = {};
    Digit remainder = digits[2];
    for (int32_t i = 1; i >= 0; i--) {
      TwoDigit n = (TwoDigit(remainder) << 32) | digits[i];
      quotient[i] = n / divisor;
      remainder = n % divisor;
    }

    int64_t result = int64_t((TwoDigit(quotient[1]) << 32) | quotient[0]);
    if (negative) {
      result *= -1;
      if (remainder != 0) {
        result -= 1;
        remainder = divisor - remainder;
      }
    }
    return {result, int32_t(remainder)};
  }

  /**
   * Return the absolute value of this integer.
   */

  constexpr Int96 abs() const { return {digits, false}; }

  /**
   * Return Some(Int96) if the integer value fits into a 96-bit integer.
   * Otherwise returns Nothing().
   */

  static mozilla::Maybe<Int96> fromInteger(double value);
};

/* namespace js::temporal */

#endif /* builtin_temporal_Int96_h */

Messung V0.5 in Prozent
C=97 H=93 G=94

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet am  2026-06-05) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik