OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [math/] [remainder.go] - Rev 762

Go to most recent revision | Compare with Previous | Blame | View Log

// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package math

// The original C code and the the comment below are from
// FreeBSD's /usr/src/lib/msun/src/e_remainder.c and came
// with this notice.  The go code is a simplified version of
// the original C.
//
// ====================================================
// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
//
// Developed at SunPro, a Sun Microsystems, Inc. business.
// Permission to use, copy, modify, and distribute this
// software is freely granted, provided that this notice
// is preserved.
// ====================================================
//
// __ieee754_remainder(x,y)
// Return :
//      returns  x REM y  =  x - [x/y]*y  as if in infinite
//      precision arithmetic, where [x/y] is the (infinite bit)
//      integer nearest x/y (in half way cases, choose the even one).
// Method :
//      Based on Mod() returning  x - [x/y]chopped * y  exactly.

// Remainder returns the IEEE 754 floating-point remainder of x/y.
//
// Special cases are:
//      Remainder(±Inf, y) = NaN
//      Remainder(NaN, y) = NaN
//      Remainder(x, 0) = NaN
//      Remainder(x, ±Inf) = x
//      Remainder(x, NaN) = NaN
func Remainder(x, y float64) float64 {
        return remainder(x, y)
}

func remainder(x, y float64) float64 {
        const (
                Tiny    = 4.45014771701440276618e-308 // 0x0020000000000000
                HalfMax = MaxFloat64 / 2
        )
        // special cases
        switch {
        case IsNaN(x) || IsNaN(y) || IsInf(x, 0) || y == 0:
                return NaN()
        case IsInf(y, 0):
                return x
        }
        sign := false
        if x < 0 {
                x = -x
                sign = true
        }
        if y < 0 {
                y = -y
        }
        if x == y {
                return 0
        }
        if y <= HalfMax {
                x = Mod(x, y+y) // now x < 2y
        }
        if y < Tiny {
                if x+x > y {
                        x -= y
                        if x+x >= y {
                                x -= y
                        }
                }
        } else {
                yHalf := 0.5 * y
                if x > yHalf {
                        x -= y
                        if x >= yHalf {
                                x -= y
                        }
                }
        }
        if sign {
                x = -x
        }
        return x
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.