[从头学数学] 第74节 小数乘法

剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入练气期第九层功法的修炼,
这次要修炼的目标是[小数乘法]。

正剧开始:

经过坚持不懈的努力,[机器小伟]终于进入了练气期高手的境界,这不,他已经可以开始第九层功法的修炼了。

这是小伟刚从[人叫板老师]那里得到的练气期第九层功法修炼指南:

以,小伟迫不及待的进入了对小数乘法的研究当中。

在开始乘法之前,小伟觉得需要能够更轻松地表示出小数,于是对数字类做了改进,这样,就可以产生以下的效果了:

[从头学数学] 第74节 小数乘法_第1张图片

但是,这样做的问题也是很大的,具体表现在竖式的不对位上,所以,最终,小伟选择了以下的方案:

[从头学数学] 第74节 小数乘法_第2张图片

这是小伟用来做测试的:

<span style="font-size:18px;">function myDraw() { 
    var config = new PlotConfiguration();  
    config.init();  
    config.setPreference(); 
	
	//config.setSector(1,1,1,1);
	//config.axis2D(0, 0, 180);
	
	var vertExp = new VerticalExpression();
	
	var x = 300, y = 20, r = 20;
	
	vertExp.rightAlign(1.506, x, y, r);
	
	y += 30;
	
	vertExp.rightAlign(0.15060, x, y, r);
	
	y += 30;
	
	vertExp.rightAlign(10.150601, x, y, r);
	
	y += 30;
	
	vertExp.rightAlign(0.1506000008, x, y, r);
	
	y += 30;
	
	vertExp.rightAlign(-0.1506000008, x, y, r);
	
		y += 30;
	
	vertExp.leftAlign(0.15060, x, y, r);
	
	y += 30;
	
	vertExp.leftAlign(10.150601, x, y, r);
	
	y += 30;
	
	vertExp.leftAlign(0.1506000008, x, y, r);
	
	y += 30;
	
	vertExp.leftAlign(-0.1506000008, x, y, r);
	
}</span>


好了,现在可以正式地开始修炼了。



[从头学数学] 第74节 小数乘法_第3张图片



[从头学数学] 第74节 小数乘法_第4张图片

[从头学数学] 第74节 小数乘法_第5张图片

[从头学数学] 第74节 小数乘法_第6张图片


[从头学数学] 第74节 小数乘法_第7张图片

[从头学数学] 第74节 小数乘法_第8张图片

上面这个两个水桶的问题,让[工程师阿伟]和[机器小伟]同时吃惊了,因为它的结果竟然是:

这两个桶可以盛出0-15kg范围内任意多的水来。

这是怎么回事呢?先看结果:

<span style="font-size:18px;">>>> 
-8次小桶, 3次大桶, 得到1
3次小桶, -1次大桶, 得到1
-5次小桶, 2次大桶, 得到2
6次小桶, -2次大桶, 得到2
-2次小桶, 1次大桶, 得到3
9次小桶, -3次大桶, 得到3
-10次小桶, 4次大桶, 得到4
1次小桶, 0次大桶, 得到4
-7次小桶, 3次大桶, 得到5
4次小桶, -1次大桶, 得到5
-4次小桶, 2次大桶, 得到6
7次小桶, -2次大桶, 得到6
-1次小桶, 1次大桶, 得到7
-9次小桶, 4次大桶, 得到8
2次小桶, 0次大桶, 得到8
-6次小桶, 3次大桶, 得到9
5次小桶, -1次大桶, 得到9
-3次小桶, 2次大桶, 得到10
8次小桶, -2次大桶, 得到10
0次小桶, 1次大桶, 得到11
-8次小桶, 4次大桶, 得到12
3次小桶, 0次大桶, 得到12
-5次小桶, 3次大桶, 得到13
6次小桶, -1次大桶, 得到13
-2次小桶, 2次大桶, 得到14
9次小桶, -2次大桶, 得到14
-10次小桶, 5次大桶, 得到15
1次小桶, 1次大桶, 得到15

def tmp():
    a = 4;
    b = 11;

    for i in range(1, a+b+1):
        for j in range(-10, 10):
            for k in range(-10, 10):
                if a*j + b*k == i:
                    print('{0}次小桶, {1}次大桶, 得到{2}'.format(j, k, i));

    return;</span>

用图示可以看得更清楚:

[从头学数学] 第74节 小数乘法_第9张图片

这样5kg水就量出来了。

<span style="font-size:18px;">//量水
function myDraw() { 
    var config = new PlotConfiguration();  
    config.init();  
    config.setPreference(); 
	
	//config.setSector(1,1,1,1);
	//config.axis2D(0, 0, 180);
	
	
	var y1 = 0, y2 = 0, h1= 110, h2=40, w = 30;
	
	plot.setStrokeStyle('orange');
	
	
	//
	config.setSector(4, 4, 1, 1);
	
	plot.setFillStyle('black')
		.fillText('第 1 步', 0, -20, 50);
	
	plot.setFillStyle('blue')
		.fillRect(0, h1-y1, w, y1)
		.strokeRect(0,0,w,h1);
		
	plot.setFillStyle('green')
		.fillRect(1.6*w, h1-y2, w, y2)
		.strokeRect(1.6*w, h1-h2, w, h2);
	
		//
	y1 = 80, y2 = 40;
	config.setSector(4, 4, 1, 2);
	
	plot.setFillStyle('black')
		.fillText('第 2 步', 0, -20, 50);
	
	plot.setFillStyle('blue')
		.fillRect(0, h1-y1, w, y1)
		.strokeRect(0,0,w,h1);
		
	plot.setFillStyle('green')
		.fillRect(1.6*w, h1-y2, w, y2)
		.strokeRect(1.6*w, h1-h2, w, h2);
		
			//
	y1 = 110, y2 = 10;
	config.setSector(4, 4, 1, 3);
	
	plot.setFillStyle('black')
		.fillText('第 3 步', 0, -20, 50);
	
	plot.setFillStyle('blue')
		.fillRect(0, h1-y1, w, y1)
		.strokeRect(0,0,w,h1);
		
	plot.setFillStyle('green')
		.fillRect(1.6*w, h1-y2, w, y2)
		.strokeRect(1.6*w, h1-h2, w, h2);

				//
	y1 = 10, y2 = 40;
	config.setSector(4, 4, 3, 1);
	
	plot.setFillStyle('black')
		.fillText('第 4 步', 0, -20, 50);
	
	plot.setFillStyle('blue')
		.fillRect(0, h1-y1, w, y1)
		.strokeRect(0,0,w,h1);
		
	plot.setFillStyle('green')
		.fillRect(1.6*w, h1-y2, w, y2)
		.strokeRect(1.6*w, h1-h2, w, h2);

	
}</span>


下面是量取3kg水:


量取10kg水:

[从头学数学] 第74节 小数乘法_第10张图片

其它的也都可以量出来,太神奇了。


<span style="font-size:18px;">function myDraw() { 
    var config = new PlotConfiguration();  
    config.init();  
    config.setPreference(); 
	
	//config.setSector(1,1,1,1);
	//config.axis2D(0, 0, 180);
	
	
	var x = 300, y = 20, r = 20;
	
	var vertExp = new VerticalExpression();
	vertExp.floatMul(0.049, 45,x , y, r);

	
}</span>

[从头学数学] 第74节 小数乘法_第11张图片


到现在为止,小伟的数字和竖式工具已经变成了:

<span style="font-size:18px;">/**
* @usage   数字形状
* @author  mw
* @date    2015年12月01日  星期二  15:57:45 
* @param
* @return
*
*/
function Digit() {
	//8
	this.eight = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		shape.fillRect(x, y, h, w0); //中横
		shape.fillRect(x-w, y-w, w0, h); //上左竖
		shape.fillRect(x+w, y-w, w0, h); //上右竖
		shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		shape.fillRect(x, y-h, h, w0); //上横
		shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}
	
	this.one = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽
		
		//填充
		//shape.fillRect(x, y, h, w0); //中横
		//shape.fillRect(x-w, y-w, w0, h); //上左竖
		shape.fillRect(x+w, y-w, w0, h); //上右竖
		//shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		//shape.fillRect(x, y-h, h, w0); //上横
		//shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}

	this.two = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		shape.fillRect(x, y, h, w0); //中横
		//shape.fillRect(x-w, y-w, w0, h); //上左竖
		shape.fillRect(x+w, y-w, w0, h); //上右竖
		shape.fillRect(x-w, y+w, w0, h); //下左竖
		//shape.fillRect(x+w, y+w, w0, h); //下右竖
		shape.fillRect(x, y-h, h, w0); //上横
		shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}

	this.three = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		shape.fillRect(x, y, h, w0); //中横
		//shape.fillRect(x-w, y-w, w0, h); //上左竖
		shape.fillRect(x+w, y-w, w0, h); //上右竖
		//shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		shape.fillRect(x, y-h, h, w0); //上横
		shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}

	this.four = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽
		
		//填充
		shape.fillRect(x, y, h, w0); //中横
		shape.fillRect(x-w, y-w, w0, h); //上左竖
		shape.fillRect(x+w, y-w, w0, h); //上右竖
		//shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		//shape.fillRect(x, y-h, h, w0); //上横
		//shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}
	
	this.five = function(x, y, r) {
		plot.save();

		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		shape.fillRect(x, y, h, w0); //中横
		shape.fillRect(x-w, y-w, w0, h); //上左竖
		//shape.fillRect(x+w, y-w, w0, h); //上右竖
		//shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		shape.fillRect(x, y-h, h, w0); //上横
		shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}
	
	this.six = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		shape.fillRect(x, y, h, w0); //中横
		shape.fillRect(x-w, y-w, w0, h); //上左竖
		//shape.fillRect(x+w, y-w, w0, h); //上右竖
		shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		shape.fillRect(x, y-h, h, w0); //上横
		shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}
	
	this.seven = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		//shape.fillRect(x, y, h, w0); //中横
		//shape.fillRect(x-w, y-w, w0, h); //上左竖
		shape.fillRect(x+w, y-w, w0, h); //上右竖
		//shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		shape.fillRect(x, y-h, h, w0); //上横
		//shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}
	
	this.nine = function(x, y, r) {
		plot.save();

		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		shape.fillRect(x, y, h, w0); //中横
		shape.fillRect(x-w, y-w, w0, h); //上左竖
		shape.fillRect(x+w, y-w, w0, h); //上右竖
		//shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		shape.fillRect(x, y-h, h, w0); //上横
		shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}
	
	this.zero = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		//shape.fillRect(x, y, h, w0); //中横
		shape.fillRect(x-w, y-w, w0, h); //上左竖
		shape.fillRect(x+w, y-w, w0, h); //上右竖
		shape.fillRect(x-w, y+w, w0, h); //下左竖
		shape.fillRect(x+w, y+w, w0, h); //下右竖
		shape.fillRect(x, y-h, h, w0); //上横
		shape.fillRect(x, y+h, h, w0); //下横
		
		plot.restore();
	
	}	
	
/**
* @usage   小数点
* @author  mw
* @date    2016年02月05日  星期五  09:21:38 
* @param
* @return
*
*/
	this.dot = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		shape.fillRect(x, y+h, w0, w0); //下横
		
		plot.restore();
	
	}
	
/**
* @usage   负号
* @author  mw
* @date    2016年02月05日  星期五  09:21:38 
* @param
* @return
*
*/
	this.minus = function(x, y, r) {
		plot.save();
		
		var h = r * 0.4; //字半高
		var w = h / 2.2; //字半宽
		var w0 = r *0.1; //填充宽

		//填充
		shape.fillRect(x, y, h, w0); //中横
		
		plot.restore();
	
	}	
	
			
	/**
	* @usage   绘制数字
	* @author  mw
	* @date    2015年12月01日  星期二  16:50:23 
	* @param  n [0-9] 要绘制的数字 x, y, 中心点 r 外接圆尺寸
	* @return
	*
	*/
	this.number = function(n, x, y, r) {
		switch (n) {
			case 0:case '0': this.zero(x, y, r); break;
			case 1:case '1': this.one(x, y, r); break;
			case 2:case '2': this.two(x,y,r); break;
			case 3:case '3': this.three(x, y, r); break;
			case 4:case '4': this.four(x,y,r);break;
			case 5:case '5': this.five(x,y,r);break;
			case 6:case '6': this.six(x,y,r); break;
			case 7:case '7': this.seven(x,y,r); break;
			case 8:case '8': this.eight(x,y,r); break;
			case 9:case '9': this.nine(x,y,r); break;
			case '.':this.dot(x,y,r); break;
			case '-':this.minus(x,y,r); break;
			default:break;
		
		}
	}
}
	
	
/**
* @usage   四则运算竖式
* @author  mw
* @date    2016年01月07日  星期四  12:36:11 
* @param
* @return
*
*/
function VerticalExpression() {
	/**
	* @usage   把一个数字按照基准点右对齐绘制
	* @author  mw
	* @date    2016年01月01日  星期五  13:59:42 
	* @param
	* @return
	*
	*/
	this.rightAlign = function(num, x, y, r) {
		var s = num.toString();
		var index = s.indexOf('.');
		var digitBit = s.length;
		var digit = new Digit();
		var xpos=x, ypos=y;
		var c = '';
		
		
		for (var i = digitBit-1; i > -1; i--) {
			c = s.charAt(i);
			
			if (c!='.') {
				digit.number(c, xpos, ypos, r);
				xpos -= r;
			}
			else {
				digit.number(c, xpos+0.5*r, ypos, r);
			}
		}
	}
	
/**
* @usage   把一个数字按照基准点左对齐绘制
* @author  mw
* @date    2016年01月21日  星期四  10:55:07 
* @param
* @return
*
*/
	this.leftAlign = function(num, x, y, r) {
		var s = num.toString();
		var digitBit = s.length;
		var digit = new Digit();
		var xpos=x, ypos=y;
		var c = '';
		
		for (var i = 0; i < digitBit; i++) {
			c = s.charAt(i);
			
			if (c!='.') {
				digit.number(c, xpos, ypos, r);
				xpos += r;
			}
			else {
				digit.number(c, xpos-0.5*r, ypos, r);
			}
		}
	}

/**
* @usage   小数加法竖式
* @author  mw
* @date    2016年01月21日  星期四  10:49:56 
* @param
* @return
*
*/
	this.floatAdd = function(augend, addend, precision, x, y, r) {
		
		var decimalPointPos = -1;
		
		plot.save()
			.setFillStyle('black');
			
		var result = addend + augend;
		var xBeg = x ? x : 300, yBeg = y ? y :100, r = r ? r : 20;		
		var maxBit = Math.max(addend, augend).toFixed(0).length;
		var decimalString = '';
		
		//整数和小数部分的分解
		augendDecimalPart = augend > 0 ? augend - Math.floor(augend) : Math.ceil(augend)- augend;		
		addendDecimalPart = addend > 0 ? addend - Math.floor(addend) : Math.ceil(addend)-addend;
		resultDecimalPart = result > 0 ? result - Math.floor(result) : Math.ceil(result)-result;
		
		augend = augend > 0 ? Math.floor(augend) : Math.ceil(augend);		
		addend = addend > 0 ? Math.floor(addend) : Math.ceil(addend);
		result = result > 0 ? Math.floor(result) : Math.ceil(result);		
		
		
		x = xBeg, y = yBeg + r;
		var plusPos = x - (maxBit+2) * r;
		this.rightAlign(augend, x, y, r);
		
		decimalString = augendDecimalPart.toFixed(precision);
		decimalPointPos = decimalString.indexOf('.');
		if (decimalPointPos != -1) {
			decimalString = decimalString.substr(decimalPointPos+1, precision);
			augendDecimalPart = parseInt(decimalString);
			plot.fillText('.', x, y+0.4*r, r);
			this.leftAlign(augendDecimalPart, x + r, y , r);
		}
		
		y += 1.5 * r;
		this.rightAlign(addend, x, y, r);
		
		decimalString = addendDecimalPart.toFixed(precision);
		decimalPointPos = decimalString.indexOf('.');
		if (decimalPointPos != -1) {
			decimalString = decimalString.substr(decimalPointPos+1, precision);
			addendDecimalPart = parseInt(decimalString);
			plot.fillText('.', x, y+0.4*r, r);
			this.leftAlign(addendDecimalPart, x + r, y , r);
		}
			
		plot.setFont('normal normal normal '+r.toFixed(0)+'px'+ ' arial')
			.fillText('+', plusPos, y+0.4*r, r);
		
		y += r;
		plot.beginPath()
			.moveTo(plusPos - r, y)
			.lineTo(x + (precision+ 2) *r, y)
			.closePath()
			.stroke();
			
		y += r;
		this.rightAlign(result, x, y, r);
		
		decimalString = resultDecimalPart.toFixed(precision);
		decimalPointPos = decimalString.indexOf('.');
		if (decimalPointPos != -1) {
			decimalString = decimalString.substr(decimalPointPos+1, precision);
			resultDecimalPart = parseInt(decimalString);
			plot.fillText('.', x, y+0.4*r, r);
			this.leftAlign(resultDecimalPart, x + r, y , r);
		}
			
			
		plot.restore();
	}

/**
* @usage   小数减法竖式
* @author  mw
* @date    2016年01月21日  星期四  10:49:56 
* @param
* @return
*
*/
	this.floatSub = function(minuend, subtrahend, precision, x, y, r) {
		
		var decimalPointPos = -1;
		
		plot.save()
			.setFillStyle('black');
			
		var result = minuend -subtrahend ;
		var xBeg = x ? x : 300, yBeg = y ? y :100, r = r ? r : 20;		
		var maxBit = Math.max(subtrahend, minuend).toFixed(0).length;
		var decimalString = '';
		
		//整数和小数部分的分解
		minuendDecimalPart = minuend > 0 ? minuend - Math.floor(minuend) : Math.ceil(minuend)- minuend;		
		subtrahendDecimalPart = subtrahend > 0 ? subtrahend - Math.floor(subtrahend) : Math.ceil(subtrahend)-subtrahend;
		resultDecimalPart = result > 0 ? result - Math.floor(result) : Math.ceil(result)-result;
		
		minuend = minuend > 0 ? Math.floor(minuend) : Math.ceil(minuend);		
		subtrahend = subtrahend > 0 ? Math.floor(subtrahend) : Math.ceil(subtrahend);
		result = result > 0 ? Math.floor(result) : Math.ceil(result);		
		
		
		x = xBeg, y = yBeg + r;
		var minusPos = x - (maxBit+2) * r;
		this.rightAlign(minuend, x, y, r);
		
		decimalString = minuendDecimalPart.toFixed(precision);
		decimalPointPos = decimalString.indexOf('.');
		if (decimalPointPos != -1) {
			decimalString = decimalString.substr(decimalPointPos+1, precision);
			minuendDecimalPart = parseInt(decimalString);
			plot.fillText('.', x, y+0.4*r, r);
			this.leftAlign(minuendDecimalPart, x + r, y , r);
		}
		
		y += 1.5 * r;
		this.rightAlign(subtrahend, x, y, r);
		
		decimalString = subtrahendDecimalPart.toFixed(precision);
		decimalPointPos = decimalString.indexOf('.');
		if (decimalPointPos != -1) {
			decimalString = decimalString.substr(decimalPointPos+1, precision);
			subtrahendDecimalPart = parseInt(decimalString);
			plot.fillText('.', x, y+0.4*r, r);
			this.leftAlign(subtrahendDecimalPart, x + r, y , r);
		}
			
		plot.setFont('normal normal normal '+r.toFixed(0)+'px'+ ' arial')
			.fillText('-', minusPos, y+0.4*r, r);
		
		y += r;
		plot.beginPath()
			.moveTo(minusPos - r, y)
			.lineTo(x + (precision+ 2) *r, y)
			.closePath()
			.stroke();
			
		y += r;
		this.rightAlign(result, x, y, r);
		
		if (result < 0) {
			plot.fillText('-', minusPos, y+0.2*r, r);
		}
		
		decimalString = resultDecimalPart.toFixed(precision);
		decimalPointPos = decimalString.indexOf('.');
		if (decimalPointPos != -1) {
			decimalString = decimalString.substr(decimalPointPos+1, precision);
			resultDecimalPart = parseInt(decimalString);
			plot.fillText('.', x, y+0.4*r, r);
			this.leftAlign(resultDecimalPart, x + r, y , r);
		}
			
			
		plot.restore();
	}


	/**
	* @usage   加法竖式
	* @author  mw
	* @date    2016年01月01日  星期五  13:59:42 
	* @param
	* @return
	*
	*/

	/*
		算术竖式
		Vertical arithmetic
		加数
		addend
		被加数
		Augend
		加号
		Plus
	*/
	this.add = function(augend, addend, x, y, r) {
		plot.save()
			.setFillStyle('black');
			
		var result = addend + augend;
		var xBeg = x ? x : 300, yBeg = y ? y :100, r = r ? r : 20;		
		var maxBit = Math.max(addend, augend).toFixed(0).length;
		
		x = xBeg, y = yBeg + r;
		var plusPos = x - (maxBit+2) * r;
		this.rightAlign(augend, x, y, r);
		y += 1.5 * r;
		this.rightAlign(addend, x, y, r);
		plot.setFont('normal normal normal '+r.toFixed(0)+'px'+ ' arial')
			.fillText('+', plusPos, y+0.4*r, r);
		
		y += r;
		plot.beginPath()
			.moveTo(plusPos - r, y)
			.lineTo(x + r, y)
			.closePath()
			.stroke();
			
		y += r;
		this.rightAlign(result, x, y, r);
		plot.restore();
	}

	/**
	* @usage   连加竖式
	* @author  mw
	* @date    2016年01月07日  星期四  14:39:43 
	* @param
	* @return
	*
	*/	
	this.continuousAdd = function(taskArray, x, y, r) {
		plot.save()
			.setFillStyle('black');
		var array = new Array();
		array = taskArray;
		var len = array.length;
		
		if (len < 2) return;		
		
		var result = array[0] + array[1];
		
		var xBeg = x ? x : 300, yBeg = y ? y :100, large = r ? r : 20;
		
		var maxBit = Math.max(array[0], array[1]).toFixed(0).length;
		
		x = xBeg, y = yBeg + r;
		
		var plusPos = x - (maxBit+2) * r;
		this.rightAlign(array[0], x, y, r);
		
		y += 1.5 * r;
		
		this.rightAlign(array[1], x, y, r);
		plot.setFont('normal normal normal '+r.toFixed(0)+'px'+ ' arial')
			.fillText('+', plusPos, y+0.4*r, r);
		
		y += 0.8 * r;
		
		plot.beginPath()
			.moveTo(plusPos - r, y)
			.lineTo(x + r, y)
			.closePath()
			.stroke();
		
		y += 1.0 * r;
		
		this.rightAlign(result, x, y, r);
		
		if (array.length > 2) {
			for (var i = 2; i < array.length; i++) {			
				maxBit = Math.max(result, array[i]).toFixed(0).length;			
				plusPos = x - (maxBit+2) * r;
				result += array[i];	
				
				y += 1.2 * r;
				this.rightAlign(array[i], x, y, r);
				plot.fillText('+', plusPos, y+0.4*r, r);
				
				y += 0.8 * r;
			
				plot.beginPath()
					.moveTo(plusPos - 1 * r, y)
					.lineTo(x + 1 * r, y)
					.closePath()
					.stroke();
		
				y += 1.0 * r;
				
				this.rightAlign(result, x, y, r);
			}
		
		}
	}
	
	/**
	* @usage   减法竖式
	* @author  mw
	* @date    2016年01月01日  星期五  13:59:42 
	* @param
	* @return
	*
	*/
	/*
		被减数
		Minuend
		减数
		subtrahend
		减号
		Minus sign
	*/
	this.sub = function(minuend, subtrahend, x, y, r) {
		plot.save()
			.setFillStyle('black');
			
		var result = minuend - subtrahend;
		var xBeg = x ? x : 300, yBeg = y ? y :100, large = r ? r : 20;
		
		var maxBit = Math.max(minuend, subtrahend).toFixed(0).length;
		var minusPos = x - (maxBit+2) * r;
		x = xBeg, y = yBeg+r;
		
		this.rightAlign(minuend, x, y, r);
		
		y += 1.5*r;
		this.rightAlign(subtrahend, x, y, r);
		plot.setFont('normal normal normal '+r.toFixed(0)+'px'+ ' arial')
			.fillText('-', minusPos, y+0.2*r, r);
		
		y += 0.8*r;
		plot.beginPath()
			.moveTo(minusPos -  r, y)
			.lineTo(x + r, y)
			.closePath()
			.stroke();
			
		y += 1.0*r;
		this.rightAlign(result, x, y, r);
		if (result < 0) {
			plot.fillText('-', minusPos, y+0.2*r, r);
		}
		plot.restore();
	}
	
	/**
	* @usage   连减竖式
	* @author  mw
	* @date    2016年01月07日  星期四  14:39:43 
	* @param
	* @return
	*
	*/	
	this.continuousSub = function(taskArray, x, y, r) {
		plot.save()
			.setFillStyle('black');
		var array = new Array();
		array = taskArray;
		var len = array.length;
		
		if (len < 2) return;		
		
		var result = array[0] - array[1];
		
		var xBeg = x ? x : 300, yBeg = y ? y :100, large = r ? r : 20;
		
		var maxBit = Math.max(array[0], array[1]).toFixed(0).length;
		
		x = xBeg, y = yBeg + r;
		
		var minusPos = x - (maxBit+2) * r;
		this.rightAlign(array[0], x, y, r);
		
		y += 1.5 * r;
		
		this.rightAlign(array[1], x, y, r);
		plot.setFont('normal normal normal '+r.toFixed(0)+'px'+ ' arial')
			.fillText('-', minusPos, y+0.2*r, r);
		
		y += 0.8 * r;
		
		plot.beginPath()
			.moveTo(minusPos - r, y)
			.lineTo(x + r, y)
			.closePath()
			.stroke();
		
		y += 1.0 * r;
		
		this.rightAlign(result, x, y, r);
		if (result < 0) {
			plot.fillText('-', minusPos, y+0.2*r, r);
		}
		
		if (array.length > 2) {
			for (var i = 2; i < array.length; i++) {			
				maxBit = Math.max(result, array[i]).toFixed(0).length;			
				minusPos = x - (maxBit+2) * r;
				result -= array[i];	
				
				y += 1.0 * r;
				this.rightAlign(array[i], x, y, r);
				plot.fillText('-', minusPos, y+0.4*r, r);
				
				y += 0.8 * r;
			
				plot.beginPath()
					.moveTo(minusPos - 1 * r, y)
					.lineTo(x + 1 * r, y)
					.closePath()
					.stroke();
		
				y += 1.0 * r;
				
				this.rightAlign(result, x, y, r);
				if (result < 0) {
					plot.fillText('-', minusPos, y+0.2*r, r);
				}
			}
		
		}
	}
	
	
/**
* @usage   乘法竖式
* @author  mw
* @date    2016年01月14日  星期四  09:00:33 
* @param
* @return
*
*/

/*
	multiplicand multiplier product
*/

	this.mul = function(multiplicand, multiplier, x, y, r) {
		plot.save()
			.setFillStyle('black');
			
		var result = multiplicand * multiplier;
		var xBeg = x ? x : 300, yBeg = y ? y :100, r = r ? r : 20;		
		var maxBit = Math.max(multiplicand, multiplier).toFixed(0).length;
		
		x = xBeg, y = yBeg + r;
		var mulPos = x - (maxBit+2) * r;
		this.rightAlign(multiplicand, x, y, r);
		y += 1.5 * r;
		this.rightAlign(multiplier, x, y, r);
		plot.setFont('normal normal normal '+r.toFixed(0)+'px'+ ' arial')
			.fillText('×', mulPos, y+0.4*r, r);	
			
		var multiplierArray = new Array();
		var tmp1 = multiplier;
		var tmp2 = tmp1 % 10;
		//记录乘数中有多少位非零
		var noneZero = 0;
		
		while (true) {
			multiplierArray.push(tmp2);
			
			if (tmp2 > 0) 
				noneZero++;
				
			tmp1 = (tmp1 - tmp2) / 10;
			if (tmp1 <= 0) 
				break;
			tmp2 = tmp1 % 10;
		}
		
		
		var len = multiplierArray.length;
		var product = 0;
		
		if (noneZero <= 1) {
			//只有至多一位乘数非零
		}
		else {
			y += r;
			plot.beginPath()
				.moveTo(mulPos - r, y)
				.lineTo(xBeg + r, y)
				.closePath()
				.stroke();
				
			y += r;
		
			for (var i = 0; i < len; i++) {
				
				if (multiplierArray[i] == 0) {
					/*
					if (i == 0) {
						product = multiplierArray[i] * multiplicand;
						this.rightAlign(product, x, y, r);
						y += 1.5*r;
					}*/
				}
				else {
					product = multiplierArray[i] * multiplicand;
					this.rightAlign(product, x, y, r);
					if (i < len-1) {
						y += 1.5*r;
					}
				}
				x -= r;
			}
		}
		

		y += r;
		plot.beginPath()
			.moveTo(mulPos - r, y)
			.lineTo(xBeg + r, y)
			.closePath()
			.stroke();
			
		y += r;
		
		this.rightAlign(result, xBeg, y, r);
		
		
		plot.restore();
	}
	
	/**
* @usage   小数乘法竖式
* @author  mw
* @date    2016年02月05日  星期五  10:00:29 
* @param
* @return
*
*/

/*
	multiplicand multiplier product
*/

	this.floatMul = function(multiplicand, multiplier, x, y, r) {
		plot.save()
			.setFillStyle('black');
		
		var result = multiplicand * multiplier;

		var xBeg = x ? x : 300, yBeg = y ? y :100, r = r ? r : 20;		
		var maxBit = Math.max(multiplicand.toString().length, multiplier.toString().length);
		
		x = xBeg, y = yBeg + r;
		var mulPos = x - (maxBit+2) * r;
		this.rightAlign(multiplicand, x, y, r);
		y += 1.5 * r;
		this.rightAlign(multiplier, x, y, r);
		plot.setFont('normal normal normal '+r.toFixed(0)+'px'+ ' arial')
			.fillText('×', mulPos, y+0.4*r, r);	
			
			
		//把被乘数和乘数都变成整数
		multiplicand = Math.abs(multiplicand);
		var s = multiplicand.toString();
		var index = s.indexOf('.');
		//len为字符串长度,prec1为小数部分位数,maxPrec为允许的最大精度
		//由于采用了把小数扩大10的精度倍数,做成整数的方法,所以maxPrec不能太大。
		var len = 0, prec1 = 0, prec2 = 0, maxPrec = 3;
		
		if (index > -1) {
			len = s.length;
			prec1 = len-1-index;
		
			if (prec1 < maxPrec) {
				multiplicand *= Math.pow(10, prec1);
			}
			else {
				prec1 = maxPrec;
				multiplicand *= Math.pow(10, prec1);
			}
			
			multiplicand = Math.floor(multiplicand);
		}
		
		//处理乘数
		multiplier = Math.abs(multiplier);
		s = multiplier.toString();
		index = s.indexOf('.');
		//有小数点
		if (index > -1) {
			len = s.length;
			prec2 = len-1-index;
			
			if (prec2 < maxPrec) {
				multiplier *= Math.pow(10, prec2);
			}
			else {
				prec2 = maxPrec;
				multiplier *= Math.pow(10, prec2);
			}
			
			//去尾
			multiplier = Math.floor(multiplier);
		}
		
		var multiplierArray = new Array();
		var tmp1 = multiplier;
		var tmp2 = tmp1 % 10;
		//记录乘数中有多少位非零
		var noneZero = 0;
		
		while (true) {
			multiplierArray.push(tmp2);
			
			if (tmp2 > 0) 
				noneZero++;
				
			tmp1 = (tmp1 - tmp2) / 10;
			if (tmp1 <= 0) 
				break;
			tmp2 = tmp1 % 10;
		}
		
		
		var len = multiplierArray.length;
		var product = 0;
		
		if (noneZero <= 1) {
			//只有至多一位乘数非零
		}
		else {
			y += r;
			plot.beginPath()
				.moveTo(mulPos - r, y)
				.lineTo(xBeg + r, y)
				.closePath()
				.stroke();
				
			y += r;
		
			for (var i = 0; i < len; i++) {
				
				if (multiplierArray[i] == 0) {
					/*
					if (i == 0) {
						product = multiplierArray[i] * multiplicand;
						this.rightAlign(product, x, y, r);
						y += 1.5*r;
					}*/
				}
				else {
					product = multiplierArray[i] * multiplicand;
					this.rightAlign(product, x, y, r);
					if (i < len-1) {
						y += 1.5*r;
					}
				}
				x -= r;
			}
		}
		

		y += r;
		plot.beginPath()
			.moveTo(mulPos - r, y)
			.lineTo(xBeg + r, y)
			.closePath()
			.stroke();
			
		y += r;
		
		this.rightAlign(result.toFixed(prec1+prec2), xBeg, y, r);
		
		
		plot.restore();
	}

	
	/**
	* @usage   除法竖式(简便写法)
	* @author  mw
	* @date    2016年01月06日  星期三  11:05:09 
	* @param
	* @return
	*
	*/
	this.div = function(dividend, divisor, xOffset, yOffset, r) {
		plot.save();
		/*
			被除数 dividend
			除数 divisor
			商数 quotient
			余数 remainder
		*/

		var lenOfDividend =dividend.toFixed(0).length;
		var lenOfDivisor = divisor.toFixed(0).length;
		var quotient = Math.floor(dividend/divisor);
		var lenOfQuotient = quotient.toFixed(0).length;
		var remainder = dividend - quotient * divisor;
		
		a = [divisor, dividend, quotient, remainder];
		
		//除数位置
		var x0 = xOffset + lenOfDivisor * r, y0= yOffset + 2 * r;
		//被除数位置
		var x1 = x0 + r + lenOfDividend * r, y1 = y0;
		//商位置
		var x2 = x1, y2 = yOffset;
		
		plot.beginPath()
			.bezierCurveTo(x0-r, y0+r, x0-0.5*r, y0+0.5*r, x0-0.2*r, y0-0.5*r, x0, y0-r)
	/*
			.moveTo(x0-r, y0+r)
			.lineTo(x0, y0-1*r)*/
			.closePath()
			.stroke();
		plot.beginPath()
			.moveTo(x0, y0-1*r)
			.lineTo(x2+r, y0-1*r)
			.closePath()
			.stroke();
			
		this.rightAlign(a[0], x0, y0, r);
		this.rightAlign(a[1], x1, y1, r);
		this.rightAlign(a[2], x2, y2, r);
		

		var tmp1, tmp2, tmp3, x, y;

		//x, y的初始位置
		x = x1 - (lenOfQuotient-1) *r, y = y1 + 1.5 * r;
		
		if (lenOfQuotient > 1) {
			for (var i = 0; i < lenOfQuotient; i++) {
				if (i == 0) {
					//待减
					tmp1 = (quotient.toFixed(0)[i] - '0')*divisor;
					//被减
					tmp2 = Math.floor(dividend / Math.pow(10, lenOfQuotient-i-2));
					//减得的差进入下一轮
					tmp3 = tmp2 - tmp1 * 10;
					
					this.rightAlign(tmp1, x, y, r);
					
					y += r;
					
					plot.beginPath()
						.moveTo(x0, y)
						.lineTo(x1 +r, y)
						.closePath()
						.stroke();
					y += r;
					
					if (tmp3 != 0 && quotient.toFixed(0)[i+1] - '0' > 0) {	
						this.rightAlign(tmp3,x+r, y, r);
						y += 1.5 * r;
						
					}
					
					//位置递增
					x += r;
						
				} 
				else if (i < lenOfQuotient-1 ) {
					//中间轮数
					tmp1 = (quotient.toFixed(0)[i] - '0')*divisor;

					tmp3 = tmp3*10 + (dividend.toFixed(0)[i+lenOfDividend-lenOfQuotient+1]-'0')-tmp1*10;
					if (tmp1 != 0) {
						this.rightAlign(tmp1, x, y, r);
					
						y += r;
						plot.beginPath()
							.moveTo(x0, y)
							.lineTo(x1 +r, y)
							.closePath()
							.stroke();
						y += 1.5 * r;
					}

					if (tmp3 != 0 && quotient.toFixed(0)[i+1] - '0' > 0) {
						this.rightAlign(tmp3,x+r, y, r);
						y += 1.5 * r;
					}
					
					x += r;					
					
				}
				else {
					//最后一轮
					tmp1 = (quotient.toFixed(0)[i] - '0')*divisor;
					if (tmp1 != 0) {
						this.rightAlign(tmp1, x, y, r);
						y += r;
						plot.beginPath()
							.moveTo(x0, y)
							.lineTo(x1 +r, y)
							.closePath()
							.stroke();
						y += r;
					} else {
						y -= 0.5 * r;
					}
					
					this.rightAlign(a[3],x, y, r);
				}
			}
		}
		else {
			//最后一轮
			tmp1 = quotient*divisor;
			this.rightAlign(tmp1, x, y, r);
			plot.moveTo(x0, y+r)
				.lineTo(x1 +r, y+r)
				.stroke();
				
			plot.beginPath()
				.moveTo(x0, y+r)
				.lineTo(x1 +r, y+r)
				.closePath()
				.stroke();
			this.rightAlign(a[3],x, y+2*r, r);
		}

	}


}</span>


[从头学数学] 第74节 小数乘法_第12张图片


<span style="font-size:18px;">def tmp():
    import math;
    d = 6.3;
    price = 0;

    if (d <= 3):
        price = y;
    else:
        price = 7 + math.ceil(d-3)*1.5;

    print(price);

    return;</span>


[从头学数学] 第74节 小数乘法_第13张图片

<span style="font-size:18px;">def tmp():
    import math;
    d = 8+29/60;
    price = 0;

    if (d <= 3):
        price = 0.22;
    else:
        price = 0.22 + math.ceil(d-3)*0.11;

    print(price);

    return;
	
def tmp(d, local):
    import math;
    price = 0;

    if local:       
        if (d <= 100):
            price = math.ceil(d/20)*0.80;
        else:
            price = 100/20*0.80 + math.ceil((d-100)/100)*1.20;
    else:
        if (d <= 100):
            price = math.ceil(d/20)*1.20;
        else:
            price = 100/20*1.20 + math.ceil((d-100)/100)*2.00;

    print(price);

    return;

if __name__ == '__main__':
    tmp(135, 1);
    tmp(262, 0);	</span>

本节到此结束,欲知后事如何,请看下回分解。


你可能感兴趣的:([从头学数学] 第74节 小数乘法)