强类型数值计算

阅读更多
以前曾经讨论过使用typedef来完成强类型的数值计算,最终遇到的问题是D里面没办法定义进行全局运算符重载。

最近在struct上找到点灵感,把基本类型用struct包装后使用,就可以重载运算符了,当然效率也是有保证的,D前几个版本已经完成了NRVO,struct也可以在栈上分配,所以不用担心性能,不过编译时注意打开-O选项。

简单测试了一下,性能与基本类型基本上没有差别:
template WrapStruct(T)
{
	T value;

	T opCast()
	{
		return value;
	}

	typeof(*this) opAssign(T)(T v)
	{
		value = v;
		return *this;
	}

	static typeof(*this) opCall(T)(T v)
	{
		typeof(*this) result;
		result.value = v;
		return result;
	}
}


struct Length
{
	mixin WrapStruct!(float);

	Time opDiv(Speed speed)
	{
		return Time(value / speed.value);
	}
	
	Speed opDiv(Time time)
	{
		return Speed(value / time.value);
	}

	char[] toString()
	{
		return std.string.format("%f m", value);
	}
}

struct Speed
{
	mixin WrapStruct!(float);

	Length opMul(Time time)
	{
		return Length(value * time.value);
	}

	char[] toString()
	{
		return std.string.format("%f m/s", value);
	}
}

struct Time
{
	mixin WrapStruct!(float);

	Length opMul(Speed speed)
	{
		return Length(value * speed.value);
	}

	char[] toString()
	{
		return std.string.format("%f s", value);
	}
}


import std.stdio;
import std.date;

void main()
{
	{
		Length length = 30;
		Speed speed = 3;
		Time time = length / speed;
		assert(cast(float)time == 10);

		time = 5;
		speed = length / time;
		assert(cast(float)speed == 6);
	}

	{
		long start = getUTCtime();
		float length = 3;
		float speed = 1.5;
		float time;
		for (int i=0; i<100000000; ++i)
		{
			time = length / speed;
		}
		writefln(getUTCtime() - start);
	}

	{
		long start = getUTCtime();
		Length length = 3;
		Speed speed = 1.5;
		Time time;
		for (int i=0; i<100000000; ++i)
		{
			time = length / speed;
		}
		writefln(getUTCtime() - start);
	}
}

你可能感兴趣的:(C,C++,C#,F#)