请教:Dx对数值计算的影响?
我在一个平面测量软件的开发过程中,要使用相关的数值计算,同时使用DirectX来显示相关的计算结果,在此过程中,发现当启用DirectX后,double的计算精度会发生变化,从而导致数值计算结果不准。或者,在数值计算软件中,不能使用DirectX?环境: 2005 SP2;或 2008
语言:C#
DirectX版本:C#开发版(9.0C版),版本号:1.0.2902.0
联系方式:QQ : 249445640;
E-Mail: 249445640@
1、 未定义 Device 设备时:
此时,double 计算结果正确!
2、 定义 Device设备后:
此时,double计算结果出现误差!
3、 注销 Device设备后:
结果,仍然有误差!
4、 重复计算:
上述各类计算方式,在相同条件下,其计算结果是可靠的,即多次重复计算,其结果相同。
5、 float 类型计算精度:
经测试,float 类型的计算,启用Dx与否,其计算精度没有影响!
计算代码如下:
double x = 1.079923890124;
double y = 2.098231232358;
double z = x + y;
this.textBox1.Text = x.ToString();
this.textBox2.Text = y.ToString();
this.textBox3.Text = z.ToString();
该段代码,在未启动 Dx时,即未创建 Device 设备时,结果为3.178155122482,正确,但在创建 Device 设备后,结果为:3.17815518379211,在创建Device设备,同时将device设备销毁后,其结果也为:17815518379211。
此时,很明显地可以看出,在启用 Dx 后,double 数据的计算精度出现了变化,结果与预期不符,分析后认为,应该是启用Dx后,double类型发生了变化导致,但变化原因、以及如何消除这种变化的措施不详!
请求:各位大虾,该类问题如何解决?
程序代码如下:
using System;
using System.Collections.Generic;
using
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX.Direct3D;
namespace testDXDouble
{
public partial class Form1 : Form
{
public Device device = null;
public Form1()
{
InitializeComponent();
}
public bool DeclareDevice(Control deviceincomponent)
{
// Set our presentation parameters
try
{
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true; // 窗口显示
presentParams.SwapEffect = SwapEffect.Discard; // 交换链表设置
presentParams.BackBufferFormat = Format.Unknown; // 未知
presentParams.EnableAutoDepthStencil = true; // Z缓冲区设置
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
//presentParams.BackBufferFormat = Format.R5G6B5;
// Create our device
device = new Device(0, DeviceType.Hardware, deviceincomponent, CreateFlags.SoftwareVertexProcessing, presentParams);
if (device == null)
device = new Device(0, DeviceType.Reference, deviceincomponent, CreateFlags.SoftwareVertexProcessing, presentParams);
// 如果硬件设备创建失败,则采用“参考光栅器”
// device 创建成功后,应对其基本的属性进行设置,如剔除模式、深度测试、反锯齿及其他的常用参数,它们一般情况下,不由用户或使用者进行自定义
device.RenderState.CullMode = Cull.CounterClockwise; // 逆时针剔除模式
//device.RenderState.DiffuseMaterialSource = ColorSource.Material;
device.RenderState.AlphaBlendEnable = true;
device.RenderState.NormalizeNormals = true;
return true;
}
catch
{
MessageBox.Show("绘图设备创建失败!");
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
DeclareDevice((Control)this.pictureBox1);
}
private void button2_Click(object sender, EventArgs e)
{
double x = 1.079923890124;
double y = 2.098231232358;
double z = x + y;
this.textBox1.Text = x.ToString();
this.textBox2.Text = y.ToString();
this.textBox3.Text = z.ToString();
}
private void button3_Click(object sender, EventArgs e)
{
device.Dispose();
}
}
}