Bugs: Browse | Submit New | Admin

[#9058] RubyCLR loses incorrectly converts Bignum to System.Double, causing loss of precision

Date:
2007-03-05 18:48
Priority:
3
Submitted By:
Justin Bailey (m4dc4p)
Assigned To:
Nobody (None)
Category:
Core
State:
Open
Summary:
RubyCLR loses incorrectly converts Bignum to System.Double, causing loss of precision

Detailed description
I found this bug when assigning large database ID keys from Ruby to a .NET data set. RubyCLR will convert a Bignum value
to a System.Double when passsing to a method that takes an Object parameter (such as DataRow's set_Item method). The
code below gives a unit test which demonstrates the problem. Note this was developed with "Drop 4" of RubyCLR,
I don't know if it works with later versions:

# == Begin Here
# Contributed by Justin Bailey (jgbailey @nospam@ gmail.com)
#

require 'rubygems'
require 'rubyclr'
require 'test/unit'

class Int64MarshalTest < Test::Unit::TestCase

	# Create two methods, one that takes an Int64 argument,
	# the other that takes a Object argument
	inline do |csharp|
		csharp.compile <<-CS
		public class Class1 
		{
			public static System.Int64 returnArgObject(object arg)
			{
			  // Argument here is actually a double (from RubyCLR)
				return System.Convert.ToInt64(arg);
			}

			public static System.Int64 returnArgInt64(System.Int64 arg)
			{
				return arg;
			}
		}
		CS
	end
	
	def test_precision_loss
		# RubyCLR converts the value below
		# into a double when passing it to returnArgObject
		#
		# This causes a loss of precision when the value comes back. 
		
		# This is bad when that value is a database ID and 
		# it is being assigned to a .NET data set from Ruby ...
		
		int64 = 616013000000000008

		# This works because RubyCLR correctly marshals to a In64
		result = Class1.returnArgInt64(int64)
		assert int64 == result, "int64 did not come back from returnArgInt64 with the same value. Instead, came back
as: #{result}"

		# This fails because int64 is passed as a Double type
		# to returnArgObject.
		result = Class1.returnArgObject(int64)
		assert int64 == result, "int64 did not come back from returnArgObject with the same value. Instead, came back
as: #{result}"

	end

end

		

Add A Comment: Notepad

Please login


Followup

No Followups Have Been Posted

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

No Changes Have Been Made to This Item