GVKun编程网logo

关于C#中Math.Round的简单问题(c#math.round()用法)

5

在本文中,您将会了解到关于关于C#中Math.Round的简单问题的新资讯,同时我们还将为您解释c#math.round()用法的相关在本文中,我们将带你探索关于C#中Math.Round的简单问题的

在本文中,您将会了解到关于关于C#中Math.Round的简单问题的新资讯,同时我们还将为您解释c#math.round()用法的相关在本文中,我们将带你探索关于C#中Math.Round的简单问题的奥秘,分析c#math.round()用法的特点,并给出一些关于Android的简单适配问题、c# – decimal.Round和Math.Round之间的差异、c# – 使用Math.Round进行舍入问题、c# – 在x64平台上Math.Round的性能显着下降的实用技巧。

本文目录一览:

关于C#中Math.Round的简单问题(c#math.round()用法)

关于C#中Math.Round的简单问题(c#math.round()用法)

假设我有一个表示集合中行数的int,我想确定保存集合所需的页数给出一定的页面大小.

因此,如果我的页面大小为20,集合大小为89,那么我需要5页.

Math.Round函数如何工作以获得我需要的东西?我需要舍入到下一个整数,而不是最近的整数.

谢谢你的建议.

解决方法

您根本不想使用Math.Round().您应该使用Math.Ceiling(),它将返回大于传入的double的最小整数值:

var pageSize = 20D;
var pages = Math.Ceiling(collection.Count() / pageSize);

Android的简单适配问题

Android的简单适配问题

一套图适配,按市场的最低分辨率(800*480),

    如果用到的是小的图片,放到高分辨率的手机上,小图会变形但不明显;如果使用的是大图的适配,如导航图片,这时变形就很严重了,可以单独针对大图,截取对应的高分辨率的图片;

    常见手机分辨率:800*480,1280*720,1920*1080

有实力的公司会针对不同的分辨率设计不同的图片,但这样会导致应用的apk文件变大;


一共有5种适配方式:

手机密度(ppi/dpi):每英寸上分布的像素点的个数。

   

一个5英存的手机(斜边长度),分辨率为1280*720(竖直和水平方向上分布的像素个数的积),斜边上的像素为:

Math.sqrt(1280*1280+720*720)=1468;

手机密度:1468/5=293ppi



通过查询google文档可以得出手机会制动加载xhdpi文件夹下的图片


dp标示控件的宽和高,但是不能适配所有分辨率的效果,这是由于像素密度导致的




1.图片适配:不同像素密度的手机会去加载不同文件夹下的图片

    通过设备的分辨率和尺寸算出手机密度,再查找google的API,得出设备自动加载对应文件夹下的图片,如果对应分辨率文件下没有所要的图片,则找高分辨率对应文件夹下的图片


不同分辨率对应优先加载的文件夹中图片如下:

320*240        ldpi文件夹

480*320        mdpi

800*480        hdpi

1280*720      xhdpi

1920*1080    xxhdpi


在不同的图片文件下dp对应的px单位换算

ldpi     1dp=  0.75px

mdpi    1dp=1px

hdpi      1dp=1.5px  

xhdpi  1dp=2px


2.dimens.xml适配:不同像素密度的手机会去加载不同的dimens.xml文件

    复制values文件夹,重命名对应分辨率的文件如:values-1280x720,只保留dimens.xml文件,修改属性的值达到想要的效果,如width的值原来是160,想要高分辨率的达到的效果一样则修改为180,将布局文件中引用由固定值改为@dimen/width即可,手机会根据不同分辨率加载不同的高度,从而达到相同的效果,需要注意的是需要在原先的dimens.xml中也配置width属性,否则会报错:找不到属性

    


3.layout布局适配 :不同像素密度的手机会去加载不同文件夹下的布局文件

成本高,不常见

    复制layout文件夹,重命名layout-1280x720,写布局文件,则1280*720的分辨率手机会去加载这个文件夹中的布局文件


4. java代码适配:获取手机屏幕的宽高,按照屏幕宽高的百分比去设置控件的宽高

    在类中获取屏幕宽和高

        DisplayMetrics displayMetrics=new DisplayMetrics();

  getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);    

设置控件的宽、高,先将规则设置在父控件上,再作用在子控件上,

RelativeLayout.LayoutParams layoutParams=

    new RelativeLayout.LayoutParams((int)(displayMetrics.widthPixel/2+0.5),

      (int)(displayMetrics.heightPixels/2+0.5));//+0.5提高精确度

tv.setLayoutParams(layoutParams);

//注意,父控件和布局文件中的一定要一致,否则运行出错:ClassCastException类转换异常


将控件的主题头去掉,2种方法,代码和配置文件中,其中一种,是在清单文件中对应的Activity节点下配置theme属性,Light标示背景色

    <activity   android:theme="@android :style/Theme.Light.NoTitleBar.Fullscreen"

在Activity的代码中:

    requestWindowFeature(Window.FEATURE_NO_TITLE);

必须放到控件加载的前面。


5. 权重适配:剩余控件的分配规则

    权重只能在线性布局中使用,无法在相对布局中使用。如果在水平方向上使用权重则在水平方向上的宽度设为0,如果在竖直方向上设置权重则在竖直方向上设置高度为0


c# – decimal.Round和Math.Round之间的差异

c# – decimal.Round和Math.Round之间的差异

C#中Math.Round和decimal.Round函数有什么区别?

解决方法

没有区别.

Math.Round(十进制)源代码:

public static Decimal Round(Decimal d) {
        return Decimal.Round(d,0);
}

Reference Source .NET Framework

编辑:

为了澄清,decimal.cs类的源代码:

public static Decimal Round(Decimal d) {
        return Round(d,0);
}

c# – 使用Math.Round进行舍入问题

c# – 使用Math.Round进行舍入问题

Module Module1
Public Sub Main()
    Dim values() As Double = {43.523,12.65,43.565}
    For Each value As Double In values
        Console.WriteLine("{0} --> {1}",value,Math.Round(value,2))
    Next
    Console.ReadLine()
End Sub
End Module

上面的代码结果为

> 43.523 – > 43.52
> 12.65 – > 12.65
> 43.565 – > 43.56

我需要43.565 – > 43.57而不是43.565 – > 43.56.
但我仍然需要其他43.523 – > 43.52和12.65 – > 12.65按原样舍入.

解决方法

首先,如果您关注精确的十进制值,则应考虑使用Decimal而不是Double.特别是,43.565并不能完全代表Double的开头.

但是,如果要指定“中点”的行为(即可以合理地向上或向下舍入的位置),请使用overload with a MidpointRounding parameter:

Console.WriteLine("{0} --> {1}",_
                  Math.Round(value,2,MidpointRounding.AwayFromZero))

c# – 在x64平台上Math.Round的性能显着下降

c# – 在x64平台上Math.Round的性能显着下降

当使用Math.Round转换double为int时,我注意到了一个非常显着的(〜15x)的性能下降,而x64与x86相比.我在Core i7 3770K上的64位 Windows上进行了测试.有人可以重现吗?有没有什么好的理由呢?也许有些奇怪的边界条件?

仅供参考,我将Math.Round(Test1)与2个近似值进行了比较:条件转换(Test2)和6755399441055744技巧(Test3).

运行时间为:

---------------------------
|       |   x86  |  x64   |
|-------+--------+--------|
| Test1 | 0,0662 | 0,9975 |
| Test2 | 0,1517 | 0,1513 |
| Test3 | 0,1966 | 0,0978 |
---------------------------

以下是基准代码:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace MathRoundTester
{
    class Program
    {
        private const int IterationCount = 1000000;

        private static int dummy;
        static void Main(string[] args)
        {
            var data = new double[100];
            var rand = new Random(0);
            for (int i = 0; i < data.Length; ++i)
            {
                data[i] = rand.NextDouble() * int.MaxValue * 2 +
                    int.MinValue + rand.NextDouble();
            }

            dummy ^= Test1(data);
            dummy ^= Test2(data);
            dummy ^= Test3(data);
            RecordTime(data,Test1);
            RecordTime(data,Test2);
            RecordTime(data,Test3);
            Console.WriteLine(dummy);
            Console.Read();
        }
        private static void RecordTime(double[] data,Func<double[],int> action)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            var sw = Stopwatch.StartNew();
            dummy ^= action(data);
            sw.Stop();
            Console.WriteLine((sw.ElapsedTicks / (double)Stopwatch.Frequency).ToString("F4"));
        }
        private static int Test1(double[] data)
        {
            int d = 0;
            for (int i = 0; i < IterationCount; ++i)
            {
                for (int j = 0; j < data.Length; ++j)
                {
                    var x = data[j];
                    d ^= (int)Math.Round(x);
                }
            }
            return d;
        }
        private static int Test2(double[] data)
        {
            int d = 0;
            for (int i = 0; i < IterationCount; ++i)
            {
                for (int j = 0; j < data.Length; ++j)
                {
                    var x = data[j];
                    d ^= x > 0 ? (int)(x + 0.5) : (int)(x - 0.5);
                }
            }
            return d;
        }
        [StructLayout(LayoutKind.Explicit)]
        private struct DoubleIntUnion
        {
            public DoubleIntUnion(double a)
            {
                Int = 0;
                Double = a;
            }
            [FieldOffset(0)]
            public double Double;
            [FieldOffset(0)]
            public int Int;
        }
        private static int Test3(double[] data)
        {
            int d = 0;
            for (int i = 0; i < IterationCount; ++i)
            {
                for (int j = 0; j < data.Length; ++j)
                {
                    var x = data[j];
                    d ^= new DoubleIntUnion(x + 6755399441055744.0).Int;
                }
            }
            return d;
        }
    }
}

更新2016-11-23:

安德烈·阿金欣在Andreynet / coreclr repo上贴了一个question之后,被添加到了1.2.0的里程碑.所以似乎这个问题只是一个监督,而且会被修改.

@R_301_5609@

我们来看看(int)Math.Round(data [j])的asm.

LegacyJIT-86:

01172EB0  fld         qword ptr [eax+edi*8+8]  
01172EB4  fistp       dword ptr [ebp-14h]

RyuJIT-64:

`d7350617 c4e17b1044d010  vmovsd  xmm0,qword ptr [rax+rdx*8+10h]
`d735061e e83dce605f      call    clr!COMDouble::Round (`3695d460)
`d7350623 c4e17b2ce8      vcvttsd2si ebp,xmm0

来源clr!COMDouble :: Round:

clr!COMDouble::Round:
`3695d460 4883ec58        sub     rsp,58h
`3695d464 0f29742440      movaps  xmmword ptr [rsp+40h],xmm6
`3695d469 0f57c9          xorps   xmm1,xmm1
`3695d46c f2480f2cc0      cvttsd2si rax,xmm0
`3695d471 0f297c2430      movaps  xmmword ptr [rsp+30h],xmm7
`3695d476 0f28f0          movaps  xmm6,xmm0
`3695d479 440f29442420    movaps  xmmword ptr [rsp+20h],xmm8
`3695d47f f2480f2ac8      cvtsi2sd xmm1,rax
`3695d484 660f2ec1        ucomisd xmm0,xmm1
`3695d488 7a17            jp      clr!COMDouble::Round+0x41 (`3695d4a1)
`3695d48a 7515            jne     clr!COMDouble::Round+0x41 (`3695d4a1)
`3695d48c 0f28742440      movaps  xmm6,xmmword ptr [rsp+40h]
`3695d491 0f287c2430      movaps  xmm7,xmmword ptr [rsp+30h]
`3695d496 440f28442420    movaps  xmm8,xmmword ptr [rsp+20h]
`3695d49c 4883c458        add     rsp,58h
`3695d4a0 c3              ret
`3695d4a1 440f28c0        movaps  xmm8,xmm0
`3695d4a5 f2440f5805c23a7100 
            addsd xmm8,mmword ptr [clr!_real (`37070f70)] ds:`37070f70=3fe0000000000000
`3695d4ae 410f28c0        movaps  xmm0,xmm8
`3695d4b2 e821000000      call    clr!floor (`3695d4d8)
`3695d4b7 66410f2ec0      ucomisd xmm0,xmm8
`3695d4bc 0f28f8          movaps  xmm7,xmm0
`3695d4bf 7a06            jp      clr!COMDouble::Round+0x67 (`3695d4c7)
`3695d4c1 0f8465af3c00    je      clr! ?? ::FNOdobFM::`string'+0xdd8c4 (`36d2842c)
`3695d4c7 0f28ce          movaps  xmm1,xmm6
`3695d4ca 0f28c7          movaps  xmm0,xmm7
`3695d4cd ff1505067000    call    qword ptr [clr!_imp__copysign (`3705dad8)]
`3695d4d3 ebb7            jmp     clr!COMDouble::Round+0x2c (`3695d48c)

如您所见,LegacyJIT-x86使用了非常快的fldfistp对;根据Instruction tables by Agner Fog,Haswell有以下数字:

Instruction | Latency | Reciprocal throughput
------------|---------|----------------------
FLD m32/64  | 3       | 0.5
FIST(P) m   | 7       | 1

RyuJIT-x64直接调用clr!COMDouble :: Round(LegacyJIT-x64做同样的).您可以在dotnet/coreclr回购中找到此方法的源代码.如果您正在使用版本1.0.0,则需要floatnative.cpp:

#if defined(_TARGET_X86_)
__declspec(naked)
double __fastcall COMDouble::Round(double d)
{
    LIMITED_METHOD_CONTRACT;

    __asm {
        fld QWORD PTR [ESP+4]
        frndint
        ret 8
    }
}

#else // !defined(_TARGET_X86_)
FCIMPL1_V(double,COMDouble::Round,double d) 
    FCALL_CONTRACT;

    double tempVal;
    double flrTempVal;
    // If the number has no fractional part do nothing
    // This shortcut is necessary to workaround precision loss in borderline cases on some platforms
    if ( d == (double)(__int64)d )
        return d;
    tempVal = (d+0.5);
    //We had a number that was equally close to 2 integers. 
    //We need to return the even one.
    flrTempVal = floor(tempVal);
    if (flrTempVal==tempVal) {
        if (0 != fmod(tempVal,2.0)) {
            flrTempVal -= 1.0;
        }
    }
    flrTempVal = _copysign(flrTempVal,d);
    return flrTempVal;
FCIMPLEND
#endif // defined(_TARGET_X86_)

如果您正在使用主分支,则可以在floatdouble.cpp中找到类似的代码.

FCIMPL1_V(double,double x)
    FCALL_CONTRACT;

    // If the number has no fractional part do nothing
    // This shortcut is necessary to workaround precision loss in borderline cases on some platforms
    if (x == (double)((INT64)x)) {
        return x;
    }

    // We had a number that was equally close to 2 integers.
    // We need to return the even one.

    double tempVal = (x + 0.5);
    double flrTempVal = floor(tempVal);

    if ((flrTempVal == tempVal) && (fmod(tempVal,2.0) != 0)) {
        flrTempVal -= 1.0;
    }

    return _copysign(flrTempVal,x);
FCIMPLEND

似乎完整的.NET Framework使用相同的逻辑.

因此,(int)Math.Round在x86上比在x64上运行得更快,因为不同JIT编译器的内部实现有所不同.请注意,以后可以更改此行为.

顺便说一下,您可以在BenchmarkDotNet的帮助下编写一个小型可靠的基准测试:

[LegacyJitX86Job,LegacyJitX64Job,RyuJitX64Job]
public class MathRoundBenchmarks
{
    private const int N = 100;
    private double[] data;

    [Setup]
    public void Setup()
    {
        var rand = new Random(0);
        data = new double[N];
        for (int i = 0; i < data.Length; ++i)
        {
            data[i] = rand.NextDouble() * int.MaxValue * 2 +
                      int.MinValue + rand.NextDouble();
        }
    }

    [Benchmark(OperationsPerInvoke = N)]
    public int MathRound()
    {
        int d = 0;
        for (int i = 0; i < data.Length; ++i)
            d ^= (int) Math.Round(data[i]);
        return d;
    }
}

结果:

BenchmarkDotNet.Core=v0.9.9.0
OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Core(TM) i7-4702MQ cpu 2.20GHz,ProcessorCount=8
Frequency=2143475 ticks,Resolution=466.5321 ns,Timer=TSC
CLR=MS.NET 4.0.30319.42000,Arch=64-bit RELEASE [RyuJIT]
GC=Concurrent Workstation
JitModules=clrjit-v4.6.1586.0

Type=MathRoundBenchmarks  Mode=Throughput

    Method | Platform |       Jit |     Median |    StdDev |
---------- |--------- |---------- |----------- |---------- |
 MathRound |      X64 | LegacyJit | 12.8640 ns | 0.2796 ns |
 MathRound |      X64 |    RyuJit | 13.4390 ns | 0.4365 ns |
 MathRound |      X86 | LegacyJit |  1.0278 ns | 0.0373 ns |

关于关于C#中Math.Round的简单问题c#math.round()用法的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android的简单适配问题、c# – decimal.Round和Math.Round之间的差异、c# – 使用Math.Round进行舍入问题、c# – 在x64平台上Math.Round的性能显着下降等相关知识的信息别忘了在本站进行查找喔。

本文标签: