gpt4 book ai didi

c# - Marshal C++ float to C# float accuracy 问题

转载 作者:行者123 更新时间:2023-11-30 03:08:20 25 4
gpt4 key购买 nike

我有一个 DBase IV 数据库。每行都有一个带有 ASCII 编码字符串的备注字段,该字符串包含两个序列化的 borland c++ 结构。我能够使用 OleDb 提取数据,使用 ASCIIEncoding 类将其重新编码为 ascii,使用 BinaryReader 将其转换为字节,并使用 Marshal.PtrToStructure 将其转换为我的 C# 结构。我得到的数据是正确的,但是数据库中任何太大的 float 在转换为 c# 时都是完全错误的。例如,将 1149.00 的值转换为 764.9844,但将 64.00 这样的值转换为正常。我可以发布一些代码和结构,但我想一开始我尽量保持简短。我知道 float 最多只能精确到 7 位数字,但我很困惑为什么会看到这个,因为值低于该限制。

编辑:

struct cplusplusstruct // from the c++ code
{
int Number;
float P;
float ZP;
float Hours;
int Month;
int Day;
int Year;
int Hour;
int Minute;
int Second;
ULONG UPCTime;
int B;
char Name[21];
float L;
float H;
float S;
}


[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct csharpstruct //The C# struct I created
{
public int Number;
public float Pr;
public float ZP;
public float Hours;
public int Month;
public int Day;
public int Year;
public int Hour;
public int Minute;
public int Second;
public UInt32 UPCTime;
public int B;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 21)]
public string Name;
public float L;
public float H;
public float S;
}


//OLE DB Connection and query ...

//Casting data to struct
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] blob = encoding.GetBytes(memoString);
MemoryStream memoryStream = new MemoryStream(blob);
BinaryReader binaryReader = new BinaryReader(memoryStream);

int dataSize = Marshal.SizeOf(typeof(csharpstruct));
GCHandle handle = GCHandle.Alloc(binaryReader.ReadBytes(dataSize), GCHandleType.Pinned);
csharpstruct data = (csharpstruct) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(csharpstruct));

编辑:以下是 java 代码,可以很好地读取数据,但没有使用任何类型转换。

org.xBaseJ.DBF dbf = new org.xBaseJ.DBF(dbPath);
org.xBaseJ.DBF dbf = new org.xBaseJ.DBF(dbPath);
MemoField m = (MemoField) dbf.getField("MEMOFIELD");

Charset charset = Charset.forName("US-ASCII");
CharsetDecoder decoder = charset.newDecoder();
ByteBuffer trendBytes = ByteBuffer.wrap(m.getBytes());
trendBytes.order(ByteOrder.LITTLE_ENDIAN);
trendBytes.getInt();
trendBytes.getFloat();

最佳答案

您的 C# 结构中有 Pack = 1,但没有说明您的 C++ 结构是否已打包。由于您的 float (21 个字符的字符串)之前有一个奇数大小的字段,这可能会导致问题并意味着您的 float 被读取时未对齐。之前的所有内容都是 4 个字节长,因此打包不太可能给您带来问题。在继续之前,我会确保打包在 C# 和 C++ 中匹配。

关于c# - Marshal C++ float to C# float accuracy 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5095158/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com