#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include <iomanip>
#define ll long long
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
static const int MAX = 100000;
static const double PI=3.14159265358979323846;

#define EPS 1e-11
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define BOTTOM 0
#define LEFT 1
#define RIGHT 2
#define TOP 3

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;


class Point{
    public:
        double x, y;
        Point(double x = 0, double y = 0): x(x), y(y) {}
        Point operator + (Point p){
            return Point(x + p.x, y + p.y);
        }
        Point operator - (Point p){
            return Point(x - p.x, y - p.y);
        }
        Point operator * (double k){
            return Point(x * k, y * k);
        }
        Point operator / (double k){
            return Point(x / k, y / k);
        }
        double norm(){
            return x * x + y * y;
        }
        double abs(){
            return sqrt(norm());
        }
        

        bool operator < (const Point &p) const {
            return x != p.x ? x < p.x : y < p.y;
        }
        bool operator == (const Point &p) const {
            return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS ;
        }
};
typedef Point Vector;

double dot(Vector a, Vector b){
    return a.x * b.x + a.y * b.y;
}
double cross(Vector a, Vector b){
    return a.x * b.y - a.y * b.x;
}
bool isOrthogonal(Vector a, Vector b){
    return equals(dot(a, b), 0.0);
}
bool isParallel(Vector a, Vector b){
    return equals(cross(a, b), 0.0);
}

class Segment{
    public:
        Point p1, p2;
        Segment(Point p1 = Point(), Point p2 = Point()): p1(p1), p2(p2) {}

};
typedef Segment Line;

Point project(Line s, Point p){
    Vector base = s.p2 - s.p1;
    double r = dot(p - s.p1, base) / base.norm();
    return s.p1 + base * r;
}
Point reflect(Line s, Point p){
    return p + (project(s, p) - p) * 2;
}
double getDistance(Point a, Point b){
    return (a-b).abs();
}
double getDistanceLP(Line l, Point p){
    return fabs( cross(l.p2 - l.p1, p - l.p1) / (l.p2 - l.p1).abs() );
}
double getDistanceSP(Segment s, Point p){
    if(dot(s.p2 - s.p1, p - s.p1) < 0.0) return getDistance(s.p1, p);
    if(dot(s.p1 - s.p2, p - s.p2) < 0.0) return getDistance(s.p2, p);
    return getDistanceLP(s, p);
}
int ccw(Point p0, Point p1, Point p2){
    Vector v1 = p1 - p0, v2 = p2 - p0;
    if( cross(v1, v2) > EPS ) return COUNTER_CLOCKWISE;
    if( cross(v1, v2) < -EPS ) return CLOCKWISE;
    if( dot(v1, v2) < -EPS ) return ONLINE_BACK;
    if( v1.norm() < v2.norm() ) return ONLINE_FRONT;
    return ON_SEGMENT;
}
bool intersect(Point p1, Point p2, Point p3, Point p4){
    int a = ccw(p1, p2, p3) * ccw(p1, p2, p4);
    int b = ccw(p3, p4, p1) * ccw(p3, p4, p2);
    return (a <= 0 && b <= 0);
}
bool intersect(Segment s1, Segment s2){
    return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
}
double getDistanceSS(Segment s1, Segment s2){
    if( intersect(s1, s2) ) return 0.0;
    return min( min( getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2) ), min( getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2) ) );
}
Point getCrossPoint(Segment s1, Segment s2){
    Vector base = s2.p2 - s2.p1;
    double d1 = fabs( cross(base, s1.p1 - s2.p1) ) / base.abs();
    double d2 = fabs( cross(base, s1.p2 - s2.p1) ) / base.abs();
    double t = d1 / (d1 + d2);
    return s1.p1 + (s1.p2 - s1.p1) * t;
}


int main(){
    double A, B, H, M;
    cin >> A >> B >> H >> M;

    double ans;
    Point a(A*cos(2*PI * (60*H + M) / 720), A*sin(2*PI * (60*H + M) / 720));
    Point b(B*cos(2*PI * M / 60), B*sin(2*PI * M / 60));

    ans = getDistance(a,b);

    cout << fixed << setprecision(11);
    cout << ans << endl;

    return 0;
}

Measured memory_bytes: 4156