Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  SkSafeMath.h

  Sprache: C
 

/*
 * Copyright 2017 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkSafeMath_DEFINED
#define SkSafeMath_DEFINED

#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h" // IWYU pragma: keep
#include "include/private/base/SkTFitsIn.h"

#include <cstddef>
#include <cstdint>
#include <limits>

// SkSafeMath always check that a series of operations do not overflow.
// This must be correct for all platforms, because this is a check for safety at runtime.

class SkSafeMath {
public:
    SkSafeMath() = default;

    bool ok() const { return fOK; }
    explicit operator bool() const { return fOK; }

    size_t mul(size_t x, size_t y) {
        return sizeof(size_t) == sizeof(uint64_t) ? mul64(x, y) : mul32(x, y);
    }

    size_t add(size_t x, size_t y) {
        size_t result = x + y;
        fOK &= result >= x;
        return result;
    }

    /**
     *  Return a + b, unless this result is an overflow/underflow. In those cases, fOK will
     *  be set to false, and it is undefined what this returns.
     */

    int addInt(int a, int b) {
        static_assert(sizeof(int) == 4"int is not 4 bytes");
        if (b < 0 && a < std::numeric_limits<int>::min() - b) {
            fOK = false;
            return a;
        } else if (b > 0 && a > std::numeric_limits<int>::max() - b) {
            fOK = false;
            return a;
        }
        return a + b;
    }

    int subInt(int a, int b) {
        if (b == std::numeric_limits<int>::min()) {
            fOK = false;
            return a;
        }
        return addInt(a, -b);
    }

    int mulInt(int x, int y) {
        int64_t result = (int64_t)x * (int64_t)y;
        if (result > std::numeric_limits<int>::max() || result < std::numeric_limits<int>::min()) {
            fOK = false;
            return x;
        }
        return (int)result;
    }

    size_t alignUp(size_t x, size_t alignment) {
        SkASSERT(alignment && !(alignment & (alignment - 1)));
        return add(x, alignment - 1) & ~(alignment - 1);
    }

    template <typename TDst, typename TSrc> TDst castTo(TSrc value) {
        if (!SkTFitsIn<TDst, TSrc>(value)) {
            fOK = false;
        }
        return static_cast<TDst>(value);
    }

    // These saturate to their results
    static size_t Add(size_t x, size_t y);
    static size_t Mul(size_t x, size_t y);
    static size_t Align4(size_t x) {
        SkSafeMath safe;
        return safe.alignUp(x, 4);
    }

private:
    uint32_t mul32(uint32_t x, uint32_t y) {
        uint64_t bx = x;
        uint64_t by = y;
        uint64_t result = bx * by;
        fOK &= result >> 32 == 0;
        // Overflow information is capture in fOK. Return the result modulo 2^32.
        return (uint32_t)result;
    }

    uint64_t mul64(uint64_t x, uint64_t y) {
        if (x <= std::numeric_limits<uint64_t>::max() >> 32
            && y <= std::numeric_limits<uint64_t>::max() >> 32) {
            return x * y;
        } else {
            auto hi = [](uint64_t x) { return x >> 32; };
            auto lo = [](uint64_t x) { return x & 0xFFFFFFFF; };

            uint64_t lx_ly = lo(x) * lo(y);
            uint64_t hx_ly = hi(x) * lo(y);
            uint64_t lx_hy = lo(x) * hi(y);
            uint64_t hx_hy = hi(x) * hi(y);
            uint64_t result = 0;
            result = this->add(lx_ly, (hx_ly << 32));
            result = this->add(result, (lx_hy << 32));
            fOK &= (hx_hy + (hx_ly >> 32) + (lx_hy >> 32)) == 0;

            #if defined(SK_DEBUG) && defined(__clang__) && defined(__x86_64__)
                auto double_check = (unsigned __int128)x * y;
                SkASSERT(result == (double_check & 0xFFFFFFFFFFFFFFFF));
                SkASSERT(!fOK || (double_check >> 64 == 0));
            #endif

            return result;
        }
    }
    bool fOK = true;
};

#endif//SkSafeMath_DEFINED

Messung V0.5 in Prozent
C=98 H=100 G=98

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© 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

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002