Hi,

This is my first useful Julia code so far. I should have probably started 
with wrapping C-code for Decimal floating point. I'm a little conflicted, I 
see that SymPi.jl doesn't wrap all of the Python code and I thought you 
could call the rest of the functions that are missing also with my code. 
Then if I change the implementation that wouldn't work.. Right? Would 
macros help?

Is there something missing to fully be Julian? Do not care about sin, cos.. 
etc.

https://github.com/quinnj/ODBC.jl/blob/master/src/ODBC_Types.jl
typealias SQLDECIMAL Cdouble
typealias SQLNUMERIC Cdouble


module Dec_m
using PyCall
import Base.show
#import Base.parsefloat # Not sure if it is appropriate to extend 
this/these one 
#import Base.parseint
@pyimport decimal as d
@pyimport operator as o

export @D_str, Dec

#immediate?
type Dec <: Number # Or FloatingPoint?
  n::PyObject # Can I allow just Decimal not all PyObjects?

  Dec(s::String) = new(d.Decimal(s))
  Dec(s::PyObject) = new(s) # missing check to see if PyObject is Decimal 
(or a better way?)
  Dec(s::Integer) = new(string(s)) # Right way to "call" other constructor 
or use promote?
end

+(a::Dec, b::Dec) = Dec(o.add(a.n, b.n))
-(a::Dec, b::Dec) = Dec(o.sub(a.n, b.n))
*(a::Dec, b::Dec) = Dec(o.mul(a.n, b.n))
/(a::Dec, b::Dec) = Dec(o.div(a.n, b.n)) # Return Decimal or maybe even 
better a rational type..? NOT better to return floating point "to conform"?

#Int32 or Integer better? Ran into trouble either way..
<<(a::Dec, b::Int64) = a * (1 << b)

# I could chop the quotes off but maybe I'm doing this wrong, wrong Python 
function?
function show(io::IO, x::Dec)
  show(io, x.n[:__str__]())
end

# can use D"literal number" as short for Dec("number"). Better to use lower 
case d?
macro D_str(s)
  Dec(s)
end

end


Can stop reading here.. But interesting info to me below..

# from_float(f)
#    Classmethod that converts a float to a decimal number, exactly.

# normalize([context])
#    Normalize the number by stripping the rightmost trailing zeros

#Why? Should if be defined for binary floating point?
# radix()
    Return Decimal(10), the radix (base) in which the Decimal class does 
all its arithmetic. Included for compatibility with the specification.

#not sure if ___cmp___ way of Python is used in Julia. Neither if decimal's 
compare (and maybe related) needs to be implemented.
#https://docs.python.org/2/reference/datamodel.html#object.__cmp__
#"There are no implied relationships among the comparison operators. The 
truth of x==y does not imply that x!=y is false."

# __nonzero__ and __unicode__ ?!


#Not sure I can just override (and if mine is imported first?): 
https://github.com/quinnj/ODBC.jl/blob/master/src/ODBC_Types.jl
typealias SQLDECIMAL Dec
typealias SQLNUMERIC Dec

# https://github.com/JuliaLang/julia/blob/master/base/rational.jl
function convert{T<:Integer}(::Type{Rational{T}}, x::FloatingPoint)
r = rationalize(T, x, tol=0)
x == convert(typeof(x), r) || throw(InexactError())
r
end
end

convert(::Type{Rational}, x::Float64) = convert(Rational{Int64}, x)
convert(::Type{Rational}, x::Float32) = convert(Rational{Int}, x)
promote_rule{T<:Integer,S<:Integer}(::Type{Rational{T}}, ::Type{S}) = 
Rational{promote_type(T,S)}
promote_rule{T<:Integer,S<:Integer}(::Type{Rational{T}}, 
::Type{Rational{S}}) = Rational{promote_type(T,S)}
promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Rational{T}}, ::Type{S}) = 
promote_type(T,S)
widen{T}(::Type{Rational{T}}) = Rational{widen(T)}

sign(x::Rational) = sign(x.num)
signbit(x::Rational) = signbit(x.num)
copysign(x::Rational, y::Real) = copysign(x.num,y) // x.den
copysign(x::Rational, y::Rational) = copysign(x.num,y.num) // x.den
typemin{T<:Integer}(::Type{Rational{T}}) = -one(T)//zero(T)
typemax{T<:Integer}(::Type{Rational{T}}) = one(T)//zero(T)
isinteger(x::Rational) = x.den == 1

#Python has a lot of functions including some unexpected:
#https://docs.python.org/2/library/decimal.html
#logical_or(other[, context])
#logical_xor(other[, context])

#normalize([context])¶

#    Normalize the number by stripping the rightmost trailing zeros and 
converting any result equal to Decimal('0') to Decimal('0e0'). Used for
# producing canonical values for attributes of an equivalence class. For 
example, Decimal('32.100') and Decimal('0.321000e+2') both normalize to the
# equivalent value Decimal('32.1').

# radix()
#    Return Decimal(10), the radix (base) in which the Decimal class does 
all its arithmetic. Included for compatibility with the specification.

# quantize(exp[, rounding[, context[, watchexp]]])
#    Return a value equal to the first operand after rounding and having 
the exponent of the second operand.


# to_eng_string([context])
#    Convert to an engineering-type string.
#    Engineering notation has an exponent which is a multiple of 3, so 
there are up to 3 digits left of the decimal place. For example, converts 
Decimal('123E+1') to Decimal('1.23E+3')


# compare(other[, context])

#    Compare the values of two Decimal instances. This operation behaves in 
the same way as the usual comparison method __cmp__(), except that 
compare() returns a Decimal instance rather than an integer, and if either 
operand is a NaN then the result is a NaN:

Just not sure about quite vs. signaling NaN..
# compare_signal(other[, context])

#compare_total(other)

#compare_total_mag(other

# conjugate()
#    Just returns self, this method is only to comply with the Decimal 
Specification.

# is_canonical()
#    Return True if the argument is canonical and False otherwise. 
Currently, a Decimal instance is always canonical, so this operation always 
returns True.

# ???!
# rotate(other[, context])



decimal.getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, 
capitals=1, flags=[], traps=[Overflow, InvalidOperation, DivisionByZero])

 class decimal.Context(prec=None, rounding=None, traps=None, flags=None, 
Emin=None, Emax=None, capitals=1)

    Creates a new context. If a field is not specified or is None, the 
default values are copied from the DefaultContext. If the flags field is 
not specified or is None, all flags are cleared.

    The prec field is a positive integer that sets the precision for 
arithmetic operations in the context.

    The rounding option is one of:

        ROUND_CEILING (towards Infinity),
        ROUND_DOWN (towards zero),
        ROUND_FLOOR (towards -Infinity),
        ROUND_HALF_DOWN (to nearest with ties going towards zero),
        ROUND_HALF_EVEN (to nearest with ties going to nearest even 
integer),
        ROUND_HALF_UP (to nearest with ties going away from zero), or
        ROUND_UP (away from zero).
        ROUND_05UP (away from zero if last digit after rounding towards 
zero would have been 0 or 5; otherwise towards zero)


If value is a unicode string then other Unicode decimal digits are also 
permitted where digit appears above. These include decimal digits from 
various other alphabets (for example, Arabic-Indic and Devanāgarī digits) 
along with the fullwidth digits u'\uff10' through u'\uff19'.

If value is a float, the binary floating point value is losslessly 
converted to its exact decimal equivalent. This conversion can often 
require 53 or more digits of precision. For example, Decimal(float('1.1')) 
converts to 
Decimal('1.100000000000000088817841970012523233890533447265625').

Once constructed, Decimal objects are immutable.

Decimal floating point objects share many properties with the other 
built-in numeric types such as float and int. All of the usual math 
operations and special methods apply. Likewise, decimal objects can be 
copied, pickled, printed, used as dictionary keys, used as set elements, 
compared, sorted, and coerced to another type (such as float or long).

Decimal objects cannot generally be combined with floats in arithmetic 
operations: an attempt to add a Decimal to a float, for example, will raise 
a TypeError. There’s one exception to this rule: it’s possible to use 
Python’s comparison operators to compare a float instance x with a Decimal 
instance y. Without this exception, comparisons between Decimal and float 
instances would follow the general rules for comparing objects of different 
types described in the Expressions section of the reference manual, leading 
to confusing results.

>>> D = decimal.Decimal
>>> D('1.23') + D('3.45')
Decimal('4.68')

julia> u, v, w = Dec("11111113"), Dec("-11111111"), Dec("7.51111111")
(Error showing value of type (Dec,Dec,Dec):
ERROR: stack overflow
 in show at none:2 (repeats 513 times)


Reply via email to