为什么Decimal数据类型没有Epsilon字段?
从手册中,decimal值的范围是±1.0×10e-28到±7.9×10e28.
表示
Double大于零的最小正值
所以看起来,Decimal也有这样一个(非平凡的)价值.但为什么不容易获得?
我明白+1.0×10e-28正是最小的正十进制值大于零:
decimal Decimal_Epsilon = new decimal(1, 0, 0, false, 28); //1e-28m;
Run Code Online (Sandbox Code Playgroud)
顺便提一下,有几个问题可以提供有关Decimal数据类型内部表示的信息:
这是一个Epsilon有用的例子.
假设我从一些采样集和所采样本的权重(或计数)之和得到加权值.现在我想计算加权平均值.但我知道权重(或计数)的总和可能仍为零.为了防止除零,我可以做if... else...并检查零.或者我可以像这样写:
T weighted_mean = weighted_sum / (weighted_count + T.Epsilon)
Run Code Online (Sandbox Code Playgroud)
这个代码在我看来更短.或者,或者我可以跳过+ T.Epsilon,而是初始化:
T weighted_count = T.Epsilon;
Run Code Online (Sandbox Code Playgroud)
当我知道实际权重的值永远不会接近时,我就能做到这一点Epsilon.
对于某些数据类型和用例,这可能更快,因为它不涉及分支.据我所知,即使分支很短,处理器也无法将两个分支用于计算.我可能知道零点以50%的速率随机出现:=)对于Decimal,速度方面可能并不重要,甚至在第一种情况下也没有用.
我的代码可能是通用的(例如,生成的),我不想为小数写单独的代码.因此,人们希望看到它Decimal具有与其他实值类型类似的接口.
运行此代码时:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace StructLayoutTest
{
class Program
{
unsafe static void Main()
{
Console.WriteLine(IntPtr.Size);
Console.WriteLine();
Sequential s = new Sequential();
s.A = 2;
s.B = 3;
s.Bool = true;
s.Long = 6;
s.C.Int32a = 4;
s.C.Int32b = 5;
int* ptr = (int*)&s;
Console.WriteLine(ptr[0]);
Console.WriteLine(ptr[1]);
Console.WriteLine(ptr[2]);
Console.WriteLine(ptr[3]);
Console.WriteLine(ptr[4]);
Console.WriteLine(ptr[5]);
Console.WriteLine(ptr[6]);
Console.WriteLine(ptr[7]); //NB!
Console.WriteLine("Press any key");
Console.ReadKey();
}
[StructLayout(LayoutKind.Explicit)]
struct Explicit
{
[FieldOffset(0)]
public int Int32a;
[FieldOffset(4)]
public int Int32b;
}
[StructLayout(LayoutKind.Sequential, Pack …Run Code Online (Sandbox Code Playgroud) 请注意,我不太确定这个问题属于这个网站,但我尝试建设性的.
为什么代码
IntPtr ptr = new IntPtr(1234);
Console.WriteLine(string.Format("{0:X8}", ptr));
Console.WriteLine(ptr.ToString("X8"));
Console.WriteLine(string.Format("{0:X8}", ptr.ToInt32()));
Run Code Online (Sandbox Code Playgroud)
产量
1234
000004D2
000004D2
Run Code Online (Sandbox Code Playgroud)
为什么IntPtr在格式化时请求将十六进制格式直接应用于参数?有没有任何已知的论据反对设计功能 - ?
如果没有针对此类设计的论据,那么我应该通过哪个渠道向Microsoft报告此问题?
另请注意,IntPtr如果请求,调试器将以十六进制显示值.
我发现打印输出IntPtr值非常直观且相对频繁.我也找到了使用第一行的其他人编写的代码,显然期望十六进制结果,但实际上结果是不同的.我也花了一些时间来注意这个问题,这使得理解日志消息更加复杂.
为什么
17m.GetHashCode() == 17d.GetHashCode()
(m =十进制,d =双)
此外,正如预期的那样
17f.GetHashCode() != 17d.GetHashCode()
(f =浮点数)
对于net3.5和net4.0来说,这似乎都是正确的.
据我了解,这些类型的内部位表示是完全不同的.那么为什么十进制和双精度类型的哈希码对于相等的初始化值相等呢?在计算哈希值之前是否发生了一些转换?
我发现源代码Double.GetHashCode()是这样的:
//The hashcode for a double is the absolute value of the integer representation
//of that double.
//
[System.Security.SecuritySafeCritical] // auto-generated
public unsafe override int GetHashCode() {
double d = m_value;
if (d == 0) {
// Ensure that 0 and -0 have the same hash code
return 0;
}
long value = *(long*)(&d);
return unchecked((int)value) ^ ((int)(value >> …Run Code Online (Sandbox Code Playgroud) 如果使用where T : BaseT == Derived中的新方法约束泛型类型参数(调用类或调用方法),则调用Base中的方法.
为什么在方法调用中忽略类型T,即使它应该在运行时之前知道?
更新:但是,当约束使用类似于where T : IBaseBase类中的方法的接口时(不是接口中的方法,这也是不可能的).
这意味着系统实际上能够检测远远超出类型约束的类型!那么为什么在类类型约束的情况下它不会超出类型约束?
这是否意味着实现接口的Base类中的方法具有方法的隐式override关键字?
测试代码:
public interface IBase
{
void Method();
}
public class Base : IBase
{
public void Method()
{
}
}
public class Derived : Base
{
public int i = 0;
public new void Method()
{
i++;
}
}
public class Generic<T>
where T : Base
{
public void CallMethod(T obj)
{
obj.Method(); //calls Base.Method()
}
public void CallMethod2<T2>(T2 obj)
where T2 …Run Code Online (Sandbox Code Playgroud) 来自stackalloc的C#参考:
stackalloc的使用自动启用公共语言运行库(CLR)中的缓冲区溢出检测功能.如果检测到缓冲区溢出,则会尽快终止该过程,以最大程度地降低恶意代码执行的可能性.
具体来说,为.NET实现了什么样的保护机制?
它还会检测缓冲区欠载吗?对已知攻击的保护力较弱?
对于上下文,例如对于MS C++编译器,此处提供了以下信息:
Windows ISV软件安全防御:
堆栈缓冲区溢出检测功能已引入Visual Studio .NET 2002中的C/C++编译器,并在后续版本中进行了更新./ GS是一个编译器开关,指示编译器添加启动代码,函数epilog和prolog代码,以生成和检查放置在函数堆栈中的随机数.
请注意,Visual C++ 2005(及更高版本)也会重新排序堆栈上的数据,以便更难以预测地破坏该数据.示例包括:
•将缓冲区移动到比非缓冲区更高的内存.此步骤可以帮助保护驻留在堆栈上的函数指针.
•在运行时将指针和缓冲区参数移动到较低的内存,以缓解各种缓冲区溢出攻击.
结构和类
有offsetof宏和运算符。有没有办法获得位字段的类似功能,以便可以查询位字段成员的位偏移量和位大小?sizeof
可以sizeof使用 来模拟#define field_name_size n,但恐怕offsetof使用起来会变得太麻烦#define field_name_offset,因为那时似乎必须使用一些复杂的公式来考虑位字段中所有前面的成员。
在某些情况下,它可以使人们克服手动保持代码与位字段定义同步的需要,而这种需要很容易失败。
一个示例是对位字段成员的互锁写入,其中需要使用自定义函数来写入此类成员,因为编译器不提供此类功能。
此外,我了解编译器实现位字段布局的方式可能略有不同。此类宏/运算符的可用性也将减少该问题的影响。
本质上,我正在寻找一个可以为内核模式做什么的函数,它可以VirtualProtect为用户模式做什么。
我正在使用以下简化代码示例的逻辑分配内存。
PMDL mdl = MmAllocatePagesForMdl
(
LowAddress,
HighAddress,
SkipAddress,
size
);
ULONG flags = NormalPagePriority | MdlMappingNoExecute | MdlMappingNoWrite;
PVOID ptr = MmGetSystemAddressForMdlSafe
(
mdl,
flags
);
Run Code Online (Sandbox Code Playgroud)
在MdlMappingNoExecute和MdlMappingNoWrite标志只会对Win8的+效果。
此外,仅使用MmGetSystemAddressForMdlSafeI 无法NoAccess为内存区域分配例如保护。
是否有任何额外的或替代的 API-s 我可以使用,以便我可以修改分配内存的页面保护?
hack 也可以,因为目前此功能不会在生产代码中使用。
每当WinDbg中遇到断点时,是否可以运行某些外部应用程序?
我有多个运行在不同主机上的虚拟机,当其中一个达到断点时,我想得到通知。时不时地在RDP窗口之间打乱,只是为了检查某些WinDbg现在是否偶然碰到了某个断点,这会分散注意力。
我已经知道WinDbg可能会在击中断点时闪烁标题栏或播放声音。
目前,我想我可以使用脚本来观察日志文件的尾部,并在向日志文件添加一些适当的模式时启动外部应用程序。但是基于WinDbg的解决方案会更好。
我在调试或发布时遇到此错误
错误1错误C2678:二进制"!=":没有操作员发现这需要类型的左边的操作数"的std :: ofstream的"(或没有可接受的转换)C:\用户\ yuser \桌面\注射器\注射器\ WriteLog.h 27 1注射器
谁能帮我解决这个问题
码 Writelog.h
#include <windows.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <conio.h>
#include <stdio.h>
#include <iostream>
#pragma warning(disable:4996)
using namespace std;
ofstream ofile;
char dlldir[320];
char LogFileName[20] = "Log.txt"; //Change this if you want
char *GetDirectoryFile(char *filename){
static char path[320];
strcpy(path, dlldir);
strcat(path, filename);
return path;
}
void WriteLog(const char *fmt, ...){
if (ofile != NULL) <<< Problem is here on( ! ) gives error
{
if (!fmt) { return; }
va_list …Run Code Online (Sandbox Code Playgroud) c# ×5
.net ×4
c++ ×2
decimal ×2
binary ×1
bit-fields ×1
c ×1
double ×1
epsilon ×1
generics ×1
gethashcode ×1
hex ×1
inheritance ×1
intptr ×1
method-call ×1
overriding ×1
stackalloc ×1
structlayout ×1
tostring ×1
unsafe ×1
windbg ×1