`
qiezi
  • 浏览: 497747 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

强类型数值计算

    博客分类:
  • D
阅读更多
以前曾经讨论过使用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);
	}
}
分享到:
评论
12 楼 qiezi 2007-04-12  
是这样的 
11 楼 soulmachine 2007-04-12  
我以为你能用C++的宏和typedef引入新的类型,开始很是惊奇。现在你的意思是:用C++的带参宏取代D的模板。我的意思再明确一下,不知对不对:C++中引入新的类型只能用struct或class自定义,而D中则多了一个手段,就是typedef。
10 楼 qiezi 2007-04-12  
我说的typedef就是D里面的,本身就是强类型的:
typedef int Length;
typedef int Time;

这2个类型不能相互赋值,除非强制转型。就连int要赋给Length也要转型,这可能不如上面写的struct方便。改用struct的主要原因就是D里面无法重载全局运算符。

我说C++宏可以实现mixin的功能,这个功能原本就是宏做的事啊。演示代码把上面的D模板改成宏就行了,语法上处理成C++的,肯定也很容易写。
9 楼 soulmachine 2007-04-12  
#include <iostream>

typedef int  myInt1;
typedef int  myInt2;

int main(int argc, char* argv[])
{
myInt1 a = 1;
myInt2 b = 2;
b = a;
std::cout << b;
return 0;
}

#include <iostream>

#define myInt1 int 
#define myInt2 int 

int main(int argc, char* argv[])
{
myInt1 a = 1;
myInt2 b = 2;
b = a;
std::cout << b;
return 0;
}

在C++中宏和typedef只是为类型取了别名,并不象D中的typedef那样引入了新的类型。qiezi能否给出一段用宏或typedef提供更丰富类型的代码?
8 楼 qiezi 2007-04-12  
C++也可以用宏的,D的语法是要简洁一些。原本想用typedef,更轻量一些,后来发现还是得用struct。
7 楼 soulmachine 2007-04-12  
在C++把同一个基本类型提升为更强的类型,似乎只能用struct 或class对其进行封装(目前只知道这种做法)。你的这段代码核心是一样的,用了struct提供更强的类型,只不过你用了D特有的mixin减少了代码量,看起来简洁了许多
6 楼 qiezi 2007-04-11  
在不降低效率的前提下,提供更强的类型,当然也就是更丰富的值语义。C++也有类似的库这样实现,不过C++模板编译效率无法忍受,D在这方面要好得多。
5 楼 oldrev 2007-04-10  
今天够多产的啊,哈哈
4 楼 h_rain 2007-04-10  
哈哈哈哈!还行,我猜到了!
呵呵,这回也把附加功能加入了!

漂亮!
3 楼 qiezi 2007-04-10  
Length length = 3;
Time time = 2;
writefln("Length: ", length, ", Time: ", time, ", speed: ", length / time);

输出:
引用

Length: 3.000000 m, Time: 2.000000 s, speed: 1.500000 m/s
2 楼 qiezi 2007-04-10  
类型安全啊,Time * Time是不能编译通过的,当然你可以定义Length * Length结果是一个面积,你Length * Length的结果赋给一个Length或是Time都是没办法编译通过的,虽然它们只包含一个数值。有些数学(或物理?)库比较需要这种,当然我只简单探讨了一下,深入了我就外行了。
1 楼 h_rain 2007-04-10  
封装的很漂亮!

时间*速度=长度
速度*时间=长度
长度/速度=时间
长度/时间=速度

呵呵,很有趣!

只是,我没有明白,这种封装用于什么用途才有实际价值?
安全?附加功能?高层抽象?

相关推荐

    数值计算方法——误差分析.pdf

    数字计算方法,简称数值计算,是信息与计算科学专业中的核心内容,也是数学的一个分支。它主要研究各类数学问题的数值解法,这些方法能够通过计算机实现,并要求理论可靠、计算复杂性低。在学习数值计算方法时,首先...

    传热与流体流动的数值计算 (CFD不朽之作)

    《传热与流体流动的数值计算》是CFD领域的一部经典著作,对于学习和研究计算流体力学(Computational Fluid Dynamics,简称CFD)的学者来说,它具有极高的参考价值。这本书深入探讨了如何运用数值方法解决传热和流体...

    数值计算与MATLAB语言完整课件PPT

    《数值计算与MATLAB语言》是一门深入探讨数学计算方法及其在MATLAB环境中实现的课程。MATLAB(矩阵实验室)是一种强大的数值计算软件,广泛应用于工程、科学和数学领域。本课件通过PPT的形式,系统地介绍了MATLAB的...

    C++和面向对象数值计算

    C++是一种强大的编程语言,尤其在数值计算领域中有着广泛的应用。面向对象编程(Object-Oriented Programming, OOP)是C++的核心特性之一,它为编写高效、可维护的数值计算程序提供了强大的工具。 面向对象编程允许...

    电磁场数值计算法与MATLAB实现

    在教学和科研方面,MATLAB能够帮助学生和研究者快速建立起几何模型,设置边界条件、网格剖分,以及方程类型和参数,进而迅速获得数值计算结果和图形展示。这极大地降低了学习难度,提升了工作效率,使得复杂的电磁场...

    数值计算之误差分析1

    这一过程体现了数值计算的抽象性、严密性、广泛的应用性和技术性,使其成为一门与计算机紧密结合、实用性极强的学科。 #### 数值计算方法的特点 数值计算方法的独特之处在于它必须提供计算机可直接处理的算法,...

    简易Mie散射数值计算方法的研究

    ### 简易Mie散射数值计算方法的研究 #### 摘要及背景 本文主要探讨了一种改进的简易Mie散射数值计算方法。Mie散射是指当光波通过透明介质时,遇到介质中的小颗粒而发生偏转的现象。自1908年Gustav Mie首次提出了...

    一个超强的作数值计算和优化的matlab工具包sedumi

    SeDuMi,全称为“Second-Order Conic Optimization using Dual Methods of Multipliers”,是一个基于MATLAB的数值计算和优化工具包,特别适用于处理次对称锥优化问题。它由Martin Sturm开发,自1998年以来在数学...

    shuzhijisuan_matlab.rar_数值计算_matlab

    MATLAB是数值计算的优秀工具,它提供了丰富的内置函数和数据类型,支持线性代数、微积分、统计分析、优化求解等多种运算。例如,你可以使用`linalg`(线性代数)模块进行矩阵运算,如求解线性方程组、计算特征值和...

    稳态导热数值计算C代码

    "二维稳态导热数值计算C程序代码本代码可操作性强应用于C++程序"描述中,"二维稳态导热"表明了问题的维数和类型,"数值计算C程序代码"表明了解决方案的方法和语言。"本代码可操作性强应用于C++程序"表明了该程序的可...

    正交表构造及其在数值计算的应用的Matlab实现_毕业论文.pdf

    在数值计算中,正交表可以用于解决多种类型的问题,例如线性代数、数值分析、优化问题等。在这些问题中,正交表可以作为一种强有力的工具,帮助我们快速、准确地解决问题。 Matlab是一种popular的编程语言,广泛...

    基于Matlab的径向基函数数值计算软件包.pdf

    Matlab的这些特性大大降低了数值计算软件的开发难度,提高了开发效率,并且使得软件具有较强的扩展性和良好的用户交互体验。 然而,基于Matlab开发的数值计算软件包也存在一些缺点。比如,Matlab是一个商业软件,其...

    计算机数值方法

    本课程涵盖了数值方法的基本理论、算法及其实现,旨在帮助学习者理解和掌握数值计算的技术。 首先,我们要理解“引论”部分,这是数值方法的入门,它介绍了数值方法的基本概念、重要性和局限性。在这个阶段,我们会...

    强对流指数计算程序

    这个程序是用MATLAB编写的,MATLAB是一种广泛应用的编程语言和数值计算环境,尤其适合处理复杂的数学和科学计算。 在MATLAB中,每个`.m`文件通常代表一个独立的函数或脚本。在给定的文件列表中,我们可以推测这些...

    线性拟合和多项式拟合-数值计算

    总的来说,C++中的线性拟合和多项式拟合涉及了数值计算的基本原理和技巧,包括矩阵运算、最小二乘法、动态数组的使用以及通用编程的设计思想。通过理解和掌握这些知识,开发者可以构建高效且适应性强的数据分析工具...

    计算机-后端-基于SOA架构实现符号数值混合数学计算平台.pdf

    传统上,数学计算主要分为符号计算和数值计算两种类型,但实际应用中往往需要将这两种计算方法结合起来使用。为了解决这一问题,本研究引入了SOA(Service-Oriented Architecture,面向服务架构)的设计理念,旨在...

    EV非数值并行遗传算法.pdf

    非数值计算是指在计算过程中不涉及具体的数值运算,而是采用符号表示来进行问题求解的方法。这种计算方式广泛应用于数学分析、逻辑推理等领域。在遗传算法中,非数值计算通常指的是处理非数值型数据,如字符串、排列...

Global site tag (gtag.js) - Google Analytics