2009-12-12 16 views
13

खोने के बिना कास्ट करना क्या प्रकार कास्टिंग कार्यों के संस्करण में बनाया गया है जो इकाइयों को संरक्षित करता है और यदि नहीं तो मैं उन्हें कैसे बनाऊंगा? तो उदाहरण के लिए उदाहरण के लिए मैं 1.0<s> द्वारा माप खोने या गुणा किए बिना intwithSecondsMeasure को एक फ्लोट पर कैसे डालेगा?एफ # माप का एक इकाई, उपाय प्रकार

[<Measure>] type s 
let intWithSecondsMeasure = 1<s> 
let justAFloat = float intWithSecondsMeasure 

उत्तर

11

@kvb द्वारा प्रदान किया गया उत्तर निश्चित रूप से काम करता है, लेकिन मैं इस रूपांतरण के लिए unbox ऑपरेटर का उपयोग नहीं करना चाहता। एक बेहतर, बनाया गया है कि मैं सोचता हूं कि को आईओपी के लिए एनओपी के रूप में संकलित किया जाना चाहिए (मैंने चेक नहीं किया है लेकिन अनबॉक्स शायद आईएल में unbox निर्देश के रूप में समाप्त होने जा रहा है और इस प्रकार रनटाइम प्रकार की जांच जोड़ता है)।

एफ # में यूनिट रूपांतरण करने का पसंदीदा तरीका LanguagePrimitives.TypeWithMeasure (MSDN) है।

let inline float32toFloat (x:float32<'u>) : float<'u> = 
    x |> float |> LanguagePrimitives.FloatWithMeasure 
+0

में अनदेखा करेगा I IL को जोड़ा। प्रश्न के साथ संगत होने के लिए int से फ़्लोट तक कास्ट करें। http://stackoverflow.com/a/21802111/17919 – gradbot

8

मुझे नहीं लगता है कि वहाँ एक अंतर्निहित तरीका यह करने के लिए है, लेकिन आप आसानी से अपने खुद इकाई के संरक्षण रूपांतरण समारोह को परिभाषित कर सकते हैं:

let float_unit (x:int<'u>) : float<'u> = unbox float x 
let floatWithSecondsMeasure = float_unit intWithSecondsMeasure 
3

इस सवाल का मेरा उत्तर देखें:

:

Unit-safe square roots

जो

यह आज पता चलता है

+0

विल कुछ पुस्तकालय में जाना? स्पष्ट रूप से यह नियोजित फ़्लोटविथमेजर के संदर्भ में लिखने योग्य होगा, लेकिन यह एक ऐसा कार्य करने के लिए अच्छा होगा जो स्पष्ट रूप से यूनिट-सुरक्षित सीधे उपलब्ध हो। –

+0

यह उत्तर अब एक चेतावनी देता है। "इस प्रकार का टेस्ट या डाउनकास्ट यूनिट-ऑफ-मापन 'यू' ' – gradbot

4

मैंने केवीबी और जोहान्स के उत्तरों से कोड संकलित किया।

जोहानिस जोड़ा कोष्ठकों के साथ

let float32toFloat (x:int<'u>) : float<'u> = 
    x |> float |> LanguagePrimitives.FloatWithMeasure 

.method public static float64 float32toFloat(int32 x) cil managed 
{ 
    // Code size  3 (0x3) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: conv.r8 
    IL_0002: ret 
} // end of method Program::float32toFloat 

KVB जवाब का जवाब।

let float_unit (x:int<'u>) : float<'u> = unbox (float x) 

.method public static float64 float_unit(int32 x) cil managed 
{ 
    // Code size  13 (0xd) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: conv.r8 
    IL_0002: box  [mscorlib]System.Double 
    IL_0007: unbox.any [mscorlib]System.Double 
    IL_000c: ret 
} // end of method Program::float_unit 

KVB जवाब

let float_unit (x:int<'u>) : float<'u> = unbox float x 

.method public static float64 float_unit(int32 x) cil managed 
{ 
    // Code size  19 (0x13) 
    .maxstack 8 
    IL_0000: newobj  instance void Program/[email protected]::.ctor() 
    IL_0005: call  !!0 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::UnboxGeneric<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32,float64>>(object) 
    IL_000a: ldarg.0 
    IL_000b: tail. 
    IL_000d: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32,float64>::Invoke(!0) 
    IL_0012: ret 
} // end of method Program::float_unit 
इस हस्ताक्षर के साथ
संबंधित मुद्दे